Skip to content

Commit

Permalink
Simplify and improve unlock dialogue
Browse files Browse the repository at this point in the history
  • Loading branch information
phoerious committed Dec 13, 2023
1 parent a5d50f4 commit 559bc7c
Show file tree
Hide file tree
Showing 4 changed files with 328 additions and 326 deletions.
102 changes: 62 additions & 40 deletions src/gui/DatabaseOpenWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,22 +92,27 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(openDatabase()));
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));

#ifdef WITH_XC_YUBIKEY
connect(m_deviceListener, SIGNAL(devicePlugged(bool, void*, void*)), this, SLOT(pollHardwareKey()));
#endif

m_ui->hardwareKeyLabelHelp->setIcon(icons()->icon("system-help").pixmap(QSize(12, 12)));
connect(m_ui->hardwareKeyLabelHelp, SIGNAL(clicked(bool)), SLOT(openHardwareKeyHelp()));
m_ui->keyFileLabelHelp->setIcon(icons()->icon("system-help").pixmap(QSize(12, 12)));
connect(m_ui->keyFileLabelHelp, SIGNAL(clicked(bool)), SLOT(openKeyFileHelp()));
connect(m_ui->addKeyFileLinkLabel, &QLabel::linkActivated, this, [&](const QString&) {
if (browseKeyFile()) {
toggleKeyFileComponent(true);
}
});
connect(m_ui->keyFileLineEdit, &PasswordWidget::textChanged, this, [&](const QString& text) {
if (text.isEmpty() && m_ui->keyFileLineEdit->isVisible()) {
toggleKeyFileComponent(false);
}
});
connect(m_ui->useHardwareKeyCheckBox, &QCheckBox::toggled, m_ui->hardwareKeyCombo, &QComboBox::setEnabled);

toggleHardwareKeyWidgets(false);
toggleKeyFileComponent(false);
toggleHardwareKeyComponent(false);

#ifdef WITH_XC_YUBIKEY
QSizePolicy sp = m_ui->hardwareKeyProgress->sizePolicy();
sp.setRetainSizeWhenHidden(true);
m_ui->hardwareKeyProgress->setSizePolicy(sp);

#ifdef WITH_XC_YUBIKEY
connect(m_deviceListener, SIGNAL(devicePlugged(bool, void*, void*)), this, SLOT(pollHardwareKey()));
connect(YubiKey::instance(), SIGNAL(detectComplete(bool)), SLOT(hardwareKeyResponse(bool)), Qt::QueuedConnection);

connect(YubiKey::instance(), &YubiKey::userInteractionRequest, this, [this] {
Expand All @@ -129,12 +134,26 @@ DatabaseOpenWidget::DatabaseOpenWidget(QWidget* parent)

DatabaseOpenWidget::~DatabaseOpenWidget() = default;

void DatabaseOpenWidget::toggleHardwareKeyWidgets(bool state)
void DatabaseOpenWidget::toggleKeyFileComponent(bool state)
{
m_ui->addKeyFileLinkLabel->setVisible(!state);
m_ui->selectKeyFileComponent->setVisible(state);
}

void DatabaseOpenWidget::toggleHardwareKeyComponent(bool state)
{
m_ui->hardwareKeyCombo->setVisible(state);
m_ui->hardwareKeyProgress->setVisible(false);
m_ui->hardwareKeyLabel->setVisible(state);
m_ui->hardwareKeyLabelHelp->setVisible(state);
m_ui->hardwareKeyComponent->setVisible(state);
m_ui->hardwareKeyCombo->setVisible(state && m_ui->hardwareKeyCombo->count() != 1);
if (m_ui->hardwareKeyCombo->count() == 1) {
m_ui->useHardwareKeyCheckBox->setText(
tr("Use hardware key [Serial: %1]")
.arg(m_ui->hardwareKeyCombo->itemData(m_ui->hardwareKeyCombo->currentIndex())
.value<YubiKeySlot>()
.first));
} else {
m_ui->useHardwareKeyCheckBox->setText(tr("Use hardware key"));
}
}

void DatabaseOpenWidget::showEvent(QShowEvent* event)
Expand Down Expand Up @@ -197,6 +216,7 @@ void DatabaseOpenWidget::load(const QString& filename)
auto lastKeyFiles = config()->get(Config::LastKeyFiles).toHash();
if (lastKeyFiles.contains(m_filename)) {
m_ui->keyFileLineEdit->setText(lastKeyFiles[m_filename].toString());
toggleKeyFileComponent(true);
}
}

Expand Down Expand Up @@ -401,7 +421,7 @@ QSharedPointer<CompositeKey> DatabaseOpenWidget::buildDatabaseKey()
lastChallengeResponse.remove(m_filename);

int selectionIndex = m_ui->hardwareKeyCombo->currentIndex();
if (selectionIndex > 0) {
if (m_ui->useHardwareKeyCheckBox->isChecked()) {
auto slot = m_ui->hardwareKeyCombo->itemData(selectionIndex).value<YubiKeySlot>();
auto crKey = QSharedPointer<ChallengeResponseKey>(new ChallengeResponseKey(slot));
databaseKey->addChallengeResponseKey(crKey);
Expand All @@ -423,23 +443,37 @@ void DatabaseOpenWidget::reject()
emit dialogFinished(false);
}

void DatabaseOpenWidget::browseKeyFile()
bool DatabaseOpenWidget::browseKeyFile()
{
QString filters = QString("%1 (*);;%2 (*.keyx; *.key)").arg(tr("All files"), tr("Key files"));
QString filename = fileDialog()->getOpenFileName(this, tr("Select key file"), QString(), filters);
QString filename =
fileDialog()->getOpenFileName(this, tr("Select key file"), FileDialog::getLastDir("keyfile"), filters);
if (filename.isEmpty()) {
return false;
}
FileDialog::saveLastDir("keyfile", filename, true);

if (QFileInfo(filename).canonicalFilePath() == QFileInfo(m_filename).canonicalFilePath()) {
MessageBox::warning(this,
tr("Cannot use database file as key file"),
tr("You cannot use your database file as a key file.\nIf you do not have a key file, "
"please leave the field empty."),
tr("Your database file is NOT a key file!\nIf you don't have a key file or don't know what "
"that is, you don't have to select one."),
MessageBox::Button::Ok);
filename = "";
return false;
}

if (!filename.isEmpty()) {
m_ui->keyFileLineEdit->setText(filename);
if (filename.endsWith(".kdbx")
&& MessageBox::warning(this,
tr("KeePassXC database file selected"),
tr("The file you selected looks like a database file.\nA database file is NOT a key "
"file!\n\nAre you sure you want to continue with this file?."),
MessageBox::Button::Yes | MessageBox::Button::Cancel,
MessageBox::Button::Cancel)
!= MessageBox::Yes) {
return false;
}

m_ui->keyFileLineEdit->setText(filename);
return true;
}

void DatabaseOpenWidget::pollHardwareKey()
Expand All @@ -448,10 +482,7 @@ void DatabaseOpenWidget::pollHardwareKey()
return;
}

m_ui->hardwareKeyCombo->clear();
m_ui->hardwareKeyCombo->addItem(tr("Detecting hardware keys…"));
m_ui->hardwareKeyCombo->setEnabled(false);

m_ui->hardwareKeyProgress->setVisible(true);
m_pollingHardwareKey = true;

Expand All @@ -462,13 +493,13 @@ void DatabaseOpenWidget::hardwareKeyResponse(bool found)
{
m_ui->hardwareKeyProgress->setVisible(false);
m_ui->hardwareKeyCombo->clear();
m_ui->useHardwareKeyCheckBox->setChecked(false);
m_pollingHardwareKey = false;

if (!found) {
toggleHardwareKeyWidgets(false);
toggleHardwareKeyComponent(false);
return;
}
m_ui->hardwareKeyCombo->addItem(tr("Select hardware key…"));
YubiKeySlot lastUsedSlot;
if (config()->get(Config::RememberLastKeyFiles).toBool()) {
auto lastChallengeResponse = config()->get(Config::LastChallengeResponse).toHash();
Expand All @@ -478,6 +509,7 @@ void DatabaseOpenWidget::hardwareKeyResponse(bool found)
if (split.size() > 1) {
lastUsedSlot = YubiKeySlot(split[0].toUInt(), split[1].toInt());
}
m_ui->useHardwareKeyCheckBox->setChecked(true);
}
}

Expand All @@ -491,21 +523,11 @@ void DatabaseOpenWidget::hardwareKeyResponse(bool found)
}
}

toggleHardwareKeyWidgets(true);
m_ui->hardwareKeyCombo->setEnabled(true);
toggleHardwareKeyComponent(true);
m_ui->hardwareKeyCombo->setEnabled(m_ui->useHardwareKeyCheckBox->isChecked());
m_ui->hardwareKeyCombo->setCurrentIndex(selectedIndex);
}

void DatabaseOpenWidget::openHardwareKeyHelp()
{
QDesktopServices::openUrl(QUrl("https://keepassxc.org/docs/#faq-yubikey-2fa"));
}

void DatabaseOpenWidget::openKeyFileHelp()
{
QDesktopServices::openUrl(QUrl("https://keepassxc.org/docs/#faq-keyfile-howto"));
}

void DatabaseOpenWidget::setUserInteractionLock(bool state)
{
if (state) {
Expand Down
7 changes: 3 additions & 4 deletions src/gui/DatabaseOpenWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,13 @@ protected slots:
void reject();

private slots:
void browseKeyFile();
bool browseKeyFile();
void toggleKeyFileComponent(bool state);
void toggleHardwareKeyComponent(bool state);
void pollHardwareKey();
void hardwareKeyResponse(bool found);
void openHardwareKeyHelp();
void openKeyFileHelp();

private:
void toggleHardwareKeyWidgets(bool state);
#ifdef WITH_XC_YUBIKEY
QPointer<DeviceListener> m_deviceListener;
#endif
Expand Down
Loading

0 comments on commit 559bc7c

Please sign in to comment.