diff --git a/src/gui/PasswordEdit.cpp b/src/gui/PasswordEdit.cpp index 0cc72a995..9474adb16 100644 --- a/src/gui/PasswordEdit.cpp +++ b/src/gui/PasswordEdit.cpp @@ -94,14 +94,10 @@ void PasswordEdit::setParentPasswordEdit(PasswordEdit* parent) m_passwordGeneratorAction->setVisible(false); } -void PasswordEdit::enablePasswordGenerator(bool signalOnly) +void PasswordEdit::enablePasswordGenerator() { - disconnect(m_passwordGeneratorAction); - m_passwordGeneratorAction->setVisible(true); - - if (signalOnly) { - connect(m_passwordGeneratorAction, &QAction::triggered, this, &PasswordEdit::togglePasswordGenerator); - } else { + if (!m_passwordGeneratorAction->isVisible()) { + m_passwordGeneratorAction->setVisible(true); connect(m_passwordGeneratorAction, &QAction::triggered, this, &PasswordEdit::popupPasswordGenerator); } } @@ -139,6 +135,7 @@ void PasswordEdit::popupPasswordGenerator() pwGenerator->setStandaloneMode(false); pwGenerator->setPasswordVisible(isPasswordVisible()); + pwGenerator->setPasswordLength(text().length()); connect(pwGenerator, SIGNAL(closePasswordGenerator()), &pwDialog, SLOT(close())); connect(pwGenerator, SIGNAL(appliedPassword(QString)), SLOT(setText(QString))); diff --git a/src/gui/PasswordEdit.h b/src/gui/PasswordEdit.h index 365f4cdb1..3ebc5d975 100644 --- a/src/gui/PasswordEdit.h +++ b/src/gui/PasswordEdit.h @@ -23,13 +23,15 @@ #include #include +class QDialog; + class PasswordEdit : public QLineEdit { Q_OBJECT public: explicit PasswordEdit(QWidget* parent = nullptr); - void enablePasswordGenerator(bool signalOnly = false); + void enablePasswordGenerator(); void setRepeatPartner(PasswordEdit* repeatEdit); bool isPasswordVisible() const; @@ -37,9 +39,6 @@ public slots: void setShowPassword(bool show); void updateRepeatStatus(); -signals: - void togglePasswordGenerator(); - private slots: void autocompletePassword(const QString& password); void popupPasswordGenerator(); diff --git a/src/gui/PasswordGeneratorWidget.cpp b/src/gui/PasswordGeneratorWidget.cpp index bfdbfe304..436124813 100644 --- a/src/gui/PasswordGeneratorWidget.cpp +++ b/src/gui/PasswordGeneratorWidget.cpp @@ -187,18 +187,13 @@ void PasswordGeneratorWidget::saveSettings() config()->set("generator/Type", m_ui->tabWidget->currentIndex()); } -void PasswordGeneratorWidget::reset(int length) +void PasswordGeneratorWidget::setPasswordLength(int length) { - m_ui->editNewPassword->setText(""); if (length > 0) { m_ui->spinBoxLength->setValue(length); } else { m_ui->spinBoxLength->setValue(config()->get("generator/Length", PasswordGenerator::DefaultLength).toInt()); } - - setStandaloneMode(false); - setPasswordVisible(config()->get("security/passwordscleartext").toBool()); - updateGenerator(); } void PasswordGeneratorWidget::setStandaloneMode(bool standalone) diff --git a/src/gui/PasswordGeneratorWidget.h b/src/gui/PasswordGeneratorWidget.h index 7e9390a9f..fe3f9f67f 100644 --- a/src/gui/PasswordGeneratorWidget.h +++ b/src/gui/PasswordGeneratorWidget.h @@ -49,7 +49,7 @@ public: ~PasswordGeneratorWidget(); void loadSettings(); void saveSettings(); - void reset(int length = 0); + void setPasswordLength(int length); void setStandaloneMode(bool standalone); QString getGeneratedPassword(); bool isPasswordVisible() const; diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 948e8456e..201c9628a 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -128,8 +128,6 @@ EditEntryWidget::EditEntryWidget(QWidget* parent) connect(m_iconsWidget, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage())); - m_mainUi->passwordGenerator->layout()->setContentsMargins(0, 0, 0, 0); - m_editWidgetProperties->setCustomData(m_customData.data()); } @@ -163,14 +161,8 @@ void EditEntryWidget::setupMain() connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool))); connect(m_mainUi->notesEnabled, SIGNAL(toggled(bool)), this, SLOT(toggleHideNotes(bool))); - connect(m_mainUi->passwordGenerator, SIGNAL(appliedPassword(QString)), SLOT(setGeneratedPassword(QString))); - connect(m_mainUi->passwordGenerator, SIGNAL(closePasswordGenerator()), SLOT(togglePasswordGenerator())); - m_mainUi->expirePresets->setMenu(createPresetsMenu()); connect(m_mainUi->expirePresets->menu(), SIGNAL(triggered(QAction*)), this, SLOT(useExpiryPreset(QAction*))); - - m_mainUi->passwordGenerator->hide(); - m_mainUi->passwordGenerator->reset(); } void EditEntryWidget::setupAdvanced() @@ -816,8 +808,6 @@ void EditEntryWidget::setForms(Entry* entry, bool restore) } else { m_mainUi->notesEdit->setFont(Font::defaultFont()); } - m_mainUi->passwordGenerator->setVisible(false); - m_mainUi->passwordGenerator->reset(entry->password().length()); m_advancedUi->attachmentsWidget->setReadOnly(m_history); m_advancedUi->addAttributeButton->setEnabled(!m_history); @@ -845,13 +835,12 @@ void EditEntryWidget::setForms(Entry* entry, bool restore) m_mainUi->passwordEdit->setText(entry->password()); m_mainUi->passwordEdit->setShowPassword(config()->get("security/passwordscleartext").toBool()); if (!m_history) { - m_mainUi->passwordEdit->enablePasswordGenerator(true); + m_mainUi->passwordEdit->enablePasswordGenerator(); } m_mainUi->expireCheck->setChecked(entry->timeInfo().expires()); m_mainUi->expireDatePicker->setDateTime(entry->timeInfo().expiryTime().toLocalTime()); m_mainUi->expirePresets->setEnabled(!m_history); - QList commonUsernames = m_db->commonUsernames(); m_usernameCompleterModel->setStringList(commonUsernames); QString usernameToRestore = m_mainUi->usernameComboBox->lineEdit()->text(); @@ -970,22 +959,6 @@ bool EditEntryWidget::commitEntry() return true; } - // Ask the user to apply the generator password, if open - if (m_mainUi->passwordGenerator->isVisible() - && m_mainUi->passwordGenerator->getGeneratedPassword() != m_mainUi->passwordEdit->text()) { - auto answer = MessageBox::question(this, - tr("Apply generated password?"), - tr("Do you want to apply the generated password to this entry?"), - MessageBox::Yes | MessageBox::No, - MessageBox::Yes); - if (answer == MessageBox::Yes) { - m_mainUi->passwordGenerator->applyPassword(); - } - } - - // Hide the password generator - m_mainUi->passwordGenerator->setVisible(false); - if (m_advancedUi->attributesView->currentIndex().isValid() && m_advancedUi->attributesEdit->isEnabled()) { QString key = m_attributesModel->keyByIndex(m_advancedUi->attributesView->currentIndex()); m_entryAttributes->set(key, m_advancedUi->attributesEdit->toPlainText(), m_entryAttributes->isProtected(key)); @@ -1142,22 +1115,6 @@ void EditEntryWidget::clear() hideMessage(); } -void EditEntryWidget::togglePasswordGenerator() -{ - bool visible = m_mainUi->passwordGenerator->isVisible(); - if (!visible) { - m_mainUi->passwordGenerator->regeneratePassword(); - m_mainUi->passwordGenerator->setPasswordVisible(m_mainUi->passwordEdit->isPasswordVisible()); - } - m_mainUi->passwordGenerator->setVisible(!visible); -} - -void EditEntryWidget::setGeneratedPassword(const QString& password) -{ - m_mainUi->passwordEdit->setText(password); - m_mainUi->passwordGenerator->setVisible(false); -} - #ifdef WITH_XC_NETWORKING void EditEntryWidget::updateFaviconButtonEnable(const QString& url) { diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index be994b88c..e0a67b5ea 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -83,8 +83,6 @@ private slots: void acceptEntry(); bool commitEntry(); void cancel(); - void togglePasswordGenerator(); - void setGeneratedPassword(const QString& password); #ifdef WITH_XC_NETWORKING void updateFaviconButtonEnable(const QString& url); #endif diff --git a/src/gui/entry/EditEntryWidgetMain.ui b/src/gui/entry/EditEntryWidgetMain.ui index 2be52a28e..491f35ce5 100644 --- a/src/gui/entry/EditEntryWidgetMain.ui +++ b/src/gui/entry/EditEntryWidgetMain.ui @@ -20,7 +20,65 @@ 0 - + + + + true + + + Toggle the checkbox to reveal the notes section. + + + Qt::AlignTop + + + + + + + Username field + + + + + + + + + Url field + + + + + + + Download favicon for URL + + + Download favicon for URL + + + + + + + + + URL: + + + + + + + Password field + + + QLineEdit::Password + + + + Toggle expiration @@ -33,7 +91,53 @@ - + + + + + 0 + 1 + + + + + 0 + 100 + + + + Notes field + + + + + + + Toggle notes visible + + + Toggle notes visible + + + Notes + + + + + + + Title field + + + + + + + Password: + + + + @@ -69,83 +173,6 @@ - - - - - 0 - 1 - - - - - 0 - 100 - - - - Notes field - - - - - - - Username field - - - - - - - - - - Title field - - - - - - - - - Url field - - - - - - - Download favicon for URL - - - Download favicon for URL - - - - - - - - - true - - - Toggle the checkbox to reveal the notes section. - - - Qt::AlignTop - - - - - - - URL: - - - @@ -153,36 +180,6 @@ - - - - Toggle notes visible - - - Toggle notes visible - - - Notes - - - - - - - Password: - - - - - - - Password field - - - QLineEdit::Password - - - @@ -199,12 +196,6 @@ - - PasswordGeneratorWidget - QWidget -
gui/PasswordGeneratorWidget.h
- 1 -
PasswordEdit QLineEdit diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.cpp b/src/keeshare/group/EditGroupWidgetKeeShare.cpp index 43f32b343..30098ef5d 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.cpp +++ b/src/keeshare/group/EditGroupWidgetKeeShare.cpp @@ -36,21 +36,13 @@ EditGroupWidgetKeeShare::EditGroupWidgetKeeShare(QWidget* parent) { m_ui->setupUi(this); - m_ui->togglePasswordButton->setIcon(filePath()->onOffIcon("actions", "password-show")); - m_ui->togglePasswordGeneratorButton->setIcon(filePath()->icon("actions", "password-generator")); - - m_ui->passwordGenerator->layout()->setContentsMargins(0, 0, 0, 0); - m_ui->passwordGenerator->hide(); - m_ui->passwordGenerator->reset(); - m_ui->messageWidget->hide(); m_ui->messageWidget->setCloseButtonVisible(false); m_ui->messageWidget->setAutoHideTimeout(-1); - connect(m_ui->togglePasswordButton, SIGNAL(toggled(bool)), m_ui->passwordEdit, SLOT(setShowPassword(bool))); - connect(m_ui->togglePasswordGeneratorButton, SIGNAL(toggled(bool)), SLOT(togglePasswordGeneratorButton(bool))); + m_ui->passwordEdit->enablePasswordGenerator(); + connect(m_ui->passwordEdit, SIGNAL(textChanged(QString)), SLOT(selectPassword())); - connect(m_ui->passwordGenerator, SIGNAL(appliedPassword(QString)), SLOT(setGeneratedPassword(QString))); connect(m_ui->pathEdit, SIGNAL(editingFinished()), SLOT(selectPath())); connect(m_ui->pathSelectionButton, SIGNAL(pressed()), SLOT(launchPathSelectionDialog())); connect(m_ui->typeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(selectType())); @@ -201,10 +193,6 @@ void EditGroupWidgetKeeShare::update() showSharingState(); } - - m_ui->passwordGenerator->hide(); - m_ui->togglePasswordGeneratorButton->setChecked(false); - m_ui->togglePasswordButton->setChecked(false); } void EditGroupWidgetKeeShare::clearInputs() @@ -215,24 +203,6 @@ void EditGroupWidgetKeeShare::clearInputs() m_ui->passwordEdit->clear(); m_ui->pathEdit->clear(); m_ui->typeComboBox->setCurrentIndex(KeeShareSettings::Inactive); - m_ui->passwordGenerator->setVisible(false); -} - -void EditGroupWidgetKeeShare::togglePasswordGeneratorButton(bool checked) -{ - m_ui->passwordGenerator->regeneratePassword(); - m_ui->passwordGenerator->setVisible(checked); -} - -void EditGroupWidgetKeeShare::setGeneratedPassword(const QString& password) -{ - if (!m_temporaryGroup) { - return; - } - auto reference = KeeShare::referenceOf(m_temporaryGroup); - reference.password = password; - KeeShare::setReferenceTo(m_temporaryGroup, reference); - m_ui->togglePasswordGeneratorButton->setChecked(false); } void EditGroupWidgetKeeShare::selectPath() diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.h b/src/keeshare/group/EditGroupWidgetKeeShare.h index b4e169b5a..54eef2bb0 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.h +++ b/src/keeshare/group/EditGroupWidgetKeeShare.h @@ -49,8 +49,6 @@ private slots: void selectPassword(); void launchPathSelectionDialog(); void selectPath(); - void setGeneratedPassword(const QString& password); - void togglePasswordGeneratorButton(bool checked); private: QScopedPointer m_ui; diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.ui b/src/keeshare/group/EditGroupWidgetKeeShare.ui index ad3f6dbe4..58d8dccb3 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.ui +++ b/src/keeshare/group/EditGroupWidgetKeeShare.ui @@ -6,56 +6,62 @@ 0 0 - 342 - 378 + 344 + 143 - - Form - - 0 - - - 0 - - - 0 - - - 0 + 10 - + Type: - + + + + 0 + 0 + + Sharing mode field - + Path: - + + + + 0 + 0 + + + + + 200 + 0 + + Path to share file field @@ -73,60 +79,68 @@ - + Password: - - + + + + + 0 + 0 + + + + + 200 + 0 + + + + Password field + + + QLineEdit::Password + + + + + - - - Password field + + + Qt::Horizontal - - QLineEdit::Password + + + 40 + 20 + - + - + + + + 0 + 0 + + - Toggle password visibility + Clear fields - - true - - - - - - - Toggle password generator - - - true + + Clear - - - - - - - Clear fields - - - Clear - - - @@ -145,12 +159,6 @@ - - PasswordGeneratorWidget - QWidget -
gui/PasswordGeneratorWidget.h
- 1 -
PasswordEdit QLineEdit diff --git a/tests/gui/TestGui.cpp b/tests/gui/TestGui.cpp index dd69e3042..f8fbfa7f1 100644 --- a/tests/gui/TestGui.cpp +++ b/tests/gui/TestGui.cpp @@ -58,6 +58,7 @@ #include "gui/FileDialog.h" #include "gui/MessageBox.h" #include "gui/PasswordEdit.h" +#include "gui/PasswordGeneratorWidget.h" #include "gui/SearchWidget.h" #include "gui/TotpDialog.h" #include "gui/TotpSetupDialog.h" @@ -652,52 +653,63 @@ void TestGui::testPasswordEntryEntropy() auto* passwordEdit = editEntryWidget->findChild(); QVERIFY(passwordEdit); QTest::mouseClick(passwordEdit, Qt::LeftButton); + + QTimer::singleShot(50, this, SLOT(passwordGeneratorCallback())); QTest::keyClick(passwordEdit, Qt::Key_G, Qt::ControlModifier); +} + +void TestGui::passwordGeneratorCallback() +{ + auto* pwGeneratorWidget = m_dbWidget->findChild(); + QVERIFY(pwGeneratorWidget); // Type in some password - auto* editNewPassword = editEntryWidget->findChild("editNewPassword"); - auto* entropyLabel = editEntryWidget->findChild("entropyLabel"); - auto* strengthLabel = editEntryWidget->findChild("strengthLabel"); + auto* generatedPassword = pwGeneratorWidget->findChild("editNewPassword"); + auto* entropyLabel = pwGeneratorWidget->findChild("entropyLabel"); + auto* strengthLabel = pwGeneratorWidget->findChild("strengthLabel"); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "hello"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "hello"); QCOMPARE(entropyLabel->text(), QString("Entropy: 6.38 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Poor")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "helloworld"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "helloworld"); QCOMPARE(entropyLabel->text(), QString("Entropy: 13.10 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Poor")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "password1"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "password1"); QCOMPARE(entropyLabel->text(), QString("Entropy: 4.00 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Poor")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "D0g.................."); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "D0g.................."); QCOMPARE(entropyLabel->text(), QString("Entropy: 19.02 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Poor")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "Tr0ub4dour&3"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "Tr0ub4dour&3"); QCOMPARE(entropyLabel->text(), QString("Entropy: 30.87 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Poor")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "correcthorsebatterystaple"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "correcthorsebatterystaple"); QCOMPARE(entropyLabel->text(), QString("Entropy: 47.98 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Weak")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "YQC3kbXbjC652dTDH"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "YQC3kbXbjC652dTDH"); QCOMPARE(entropyLabel->text(), QString("Entropy: 95.83 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Good")); - editNewPassword->setText(""); - QTest::keyClicks(editNewPassword, "Bs5ZFfthWzR8DGFEjaCM6bGqhmCT4km"); + generatedPassword->setText(""); + QTest::keyClicks(generatedPassword, "Bs5ZFfthWzR8DGFEjaCM6bGqhmCT4km"); QCOMPARE(entropyLabel->text(), QString("Entropy: 174.59 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Excellent")); + + QTest::mouseClick(generatedPassword, Qt::LeftButton); + QTest::keyClick(generatedPassword, Qt::Key_Escape); } void TestGui::testDicewareEntryEntropy() @@ -726,11 +738,20 @@ void TestGui::testDicewareEntryEntropy() auto* passwordEdit = editEntryWidget->findChild(); QVERIFY(passwordEdit); QTest::mouseClick(passwordEdit, Qt::LeftButton); + + QTimer::singleShot(50, this, SLOT(passwordGeneratorCallback())); QTest::keyClick(passwordEdit, Qt::Key_G, Qt::ControlModifier); +} + +void TestGui::passphraseGeneratorCallback() +{ + auto* pwGeneratorWidget = m_dbWidget->findChild(); + QVERIFY(pwGeneratorWidget); // Select Diceware - auto* tabWidget = editEntryWidget->findChild("tabWidget"); - auto* dicewareWidget = editEntryWidget->findChild("dicewareWidget"); + auto* generatedPassword = pwGeneratorWidget->findChild("editNewPassword"); + auto* tabWidget = pwGeneratorWidget->findChild("tabWidget"); + auto* dicewareWidget = pwGeneratorWidget->findChild("dicewareWidget"); tabWidget->setCurrentWidget(dicewareWidget); auto* comboBoxWordList = dicewareWidget->findChild("comboBoxWordList"); @@ -738,12 +759,15 @@ void TestGui::testDicewareEntryEntropy() auto* spinBoxWordCount = dicewareWidget->findChild("spinBoxWordCount"); spinBoxWordCount->setValue(6); - // Type in some password - auto* entropyLabel = editEntryWidget->findChild("entropyLabel"); - auto* strengthLabel = editEntryWidget->findChild("strengthLabel"); + // Verify entropy and strength + auto* entropyLabel = pwGeneratorWidget->findChild("entropyLabel"); + auto* strengthLabel = pwGeneratorWidget->findChild("strengthLabel"); QCOMPARE(entropyLabel->text(), QString("Entropy: 77.55 bit")); QCOMPARE(strengthLabel->text(), QString("Password Quality: Good")); + + QTest::mouseClick(generatedPassword, Qt::LeftButton); + QTest::keyClick(generatedPassword, Qt::Key_Escape); } void TestGui::testTotp() diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index b7798d0b2..df84f5318 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -39,6 +39,8 @@ class TestGui : public QObject protected slots: void createDatabaseCallback(); + void passwordGeneratorCallback(); + void passphraseGeneratorCallback(); private slots: void initTestCase();