From 0667f5de73815261077965c527093f6f513ff022 Mon Sep 17 00:00:00 2001 From: sithlord48 Date: Wed, 12 Feb 2025 18:05:18 -0500 Subject: [PATCH] refactor: allow the fingerprint dialog to show local keys and remote if needed --- src/apps/deskflow-gui/CMakeLists.txt | 3 +- src/apps/deskflow-gui/MainWindow.cpp | 4 + .../dialogs/FingerprintDialog.cpp | 95 +++---- .../deskflow-gui/dialogs/FingerprintDialog.h | 17 +- .../deskflow-gui/dialogs/FingerprintDialog.ui | 255 ------------------ .../widgets/FingerprintPreview.cpp | 101 +++++++ .../deskflow-gui/widgets/FingerprintPreview.h | 18 ++ src/apps/res/deskflow.qrc | 4 + .../deskflow-dark/actions/22/fingerprint.svg | 7 + .../deskflow-dark/actions/24/fingerprint.svg | 8 + .../deskflow-light/actions/22/fingerprint.svg | 10 + .../deskflow-light/actions/24/fingerprint.svg | 12 + 12 files changed, 225 insertions(+), 309 deletions(-) delete mode 100644 src/apps/deskflow-gui/dialogs/FingerprintDialog.ui create mode 100644 src/apps/deskflow-gui/widgets/FingerprintPreview.cpp create mode 100644 src/apps/deskflow-gui/widgets/FingerprintPreview.h create mode 100644 src/apps/res/icons/deskflow-dark/actions/22/fingerprint.svg create mode 100644 src/apps/res/icons/deskflow-dark/actions/24/fingerprint.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/22/fingerprint.svg create mode 100644 src/apps/res/icons/deskflow-light/actions/24/fingerprint.svg diff --git a/src/apps/deskflow-gui/CMakeLists.txt b/src/apps/deskflow-gui/CMakeLists.txt index 5a60d1d49..90afe726d 100644 --- a/src/apps/deskflow-gui/CMakeLists.txt +++ b/src/apps/deskflow-gui/CMakeLists.txt @@ -82,7 +82,6 @@ add_executable(${target} WIN32 MACOSX_BUNDLE dialogs/AddClientDialog.ui dialogs/FingerprintDialog.h dialogs/FingerprintDialog.cpp - dialogs/FingerprintDialog.ui dialogs/HotkeyDialog.cpp dialogs/HotkeyDialog.h dialogs/HotkeyDialog.ui @@ -97,6 +96,8 @@ add_executable(${target} WIN32 MACOSX_BUNDLE dialogs/SettingsDialog.ui widgets/ClientStateLabel.cpp widgets/ClientStateLabel.h + widgets/FingerprintPreview.h + widgets/FingerprintPreview.cpp widgets/KeySequenceWidget.cpp widgets/KeySequenceWidget.h widgets/NewScreenWidget.h diff --git a/src/apps/deskflow-gui/MainWindow.cpp b/src/apps/deskflow-gui/MainWindow.cpp index 57f76ab9d..bab5715b2 100644 --- a/src/apps/deskflow-gui/MainWindow.cpp +++ b/src/apps/deskflow-gui/MainWindow.cpp @@ -749,6 +749,10 @@ void MainWindow::checkFingerprint(const QString &line) const QList fingerprints{sha1, sha256}; auto dialogMode = isClient ? FingerprintDialogMode::Client : FingerprintDialogMode::Server; FingerprintDialog fingerprintDialog(this, fingerprints, dialogMode); + connect( + &fingerprintDialog, &FingerprintDialog::requestLocalPrintsDialog, this, &MainWindow::showMyFingerprint, + Qt::UniqueConnection + ); if (fingerprintDialog.exec() == QDialog::Accepted) { db.addTrusted(sha256); db.write(localPath); diff --git a/src/apps/deskflow-gui/dialogs/FingerprintDialog.cpp b/src/apps/deskflow-gui/dialogs/FingerprintDialog.cpp index ef5b4f2d3..1d4ce18ed 100644 --- a/src/apps/deskflow-gui/dialogs/FingerprintDialog.cpp +++ b/src/apps/deskflow-gui/dialogs/FingerprintDialog.cpp @@ -5,72 +5,73 @@ */ #include "FingerprintDialog.h" -#include "ui_FingerprintDialog.h" -#include "net/SecureUtils.h" +#include "widgets/FingerprintPreview.h" #include +#include #include +#include FingerprintDialog::FingerprintDialog( QWidget *parent, const QList &fingerprints, FingerprintDialogMode mode ) : QDialog(parent), - ui{new Ui::FingerprintDialog} + m_lblHeader{new QLabel(this)}, + m_lblFooter{new QLabel(this)}, + m_fingerprintPreview{new FingerprintPreview(this, fingerprints)}, + m_buttonBox{new QDialogButtonBox(this)} { - ui->setupUi(this); + setWindowIcon(QIcon::fromTheme("fingerprint")); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); - if (mode == FingerprintDialogMode::Local) { - setWindowTitle(tr("Your Fingerprints")); - ui->lblBody->setText(tr("These are the fingerprints for this computer")); - ui->lblFooter->setVisible(false); + m_lblHeader->setWordWrap(true); + m_lblFooter->setWordWrap(true); + m_lblFooter->setAlignment(Qt::AlignHCenter); + + auto layout = new QVBoxLayout(); + layout->addWidget(m_lblHeader); + layout->addSpacerItem(new QSpacerItem(0, 10, QSizePolicy::Fixed, QSizePolicy::Fixed)); + layout->addWidget(m_fingerprintPreview, 0, Qt::AlignTop | Qt::AlignHCenter); + layout->addWidget(m_lblFooter); + layout->addWidget(m_buttonBox); + setLayout(layout); + + if (mode == Local) { + setWindowTitle(tr("Local Fingerprints")); + m_lblHeader->setText(tr("Local computer's fingerprints")); + m_lblFooter->setVisible(false); + m_buttonBox->setStandardButtons(QDialogButtonBox::Ok); + connect(m_buttonBox->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &QDialog::accept); } else { + setWindowTitle(tr("Security Question")); auto body = tr("Compare the fingerprints in this dialog to those on the %1.\n" - "Only accept this dialog if they match!"); + "Only connect if they match!"); if (mode == FingerprintDialogMode::Server) { - ui->lblBody->setText(tr("A new Client is connecting\n%1").arg(body.arg(tr("client")))); + m_lblHeader->setText(tr("A new client is connecting.\n%1").arg(body.arg(tr("client")))); + m_lblFooter->setText(tr("\nDo you want connect to and trust the client?\n")); } else { - ui->lblBody->setText(tr("You are connecting to a new server\n%1").arg(body.arg(tr("server")))); + m_lblHeader->setText(tr("You are connecting to a new server.\n%1").arg(body.arg(tr("server")))); + m_lblFooter->setText(tr("\nDo you want connect to the server?\n")); } - setWindowTitle(tr("Security Question")); - ui->lblFooter->setText(tr("

Do you want to trust this fingerprint for future " - "connections? If you don't, a connection cannot be made.

")); + m_buttonBox->setStandardButtons(QDialogButtonBox::Help | QDialogButtonBox::Yes | QDialogButtonBox::No); - ui->buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); - connect(ui->buttonBox->button(QDialogButtonBox::Yes), &QPushButton::clicked, this, &QDialog::accept); - connect(ui->buttonBox->button(QDialogButtonBox::No), &QPushButton::clicked, this, &QDialog::reject); + // Use help to request a dialog with the host prints + // Help is used because its always to the furthest from the other buttons. + m_buttonBox->button(QDialogButtonBox::Help)->setText(tr("View local fingerprints")); + m_buttonBox->button(QDialogButtonBox::Help)->setIcon(QIcon::fromTheme("fingerprint")); + m_buttonBox->button(QDialogButtonBox::Help)->setToolTip(tr("Show the local machines fingerprints")); + connect( + m_buttonBox->button(QDialogButtonBox::Help), &QPushButton::clicked, this, + &FingerprintDialog::requestLocalPrintsDialog + ); + + m_buttonBox->button(QDialogButtonBox::No)->setFocus(); + connect(m_buttonBox->button(QDialogButtonBox::No), &QPushButton::clicked, this, &QDialog::reject); + connect(m_buttonBox->button(QDialogButtonBox::Yes), &QPushButton::clicked, this, &QDialog::accept); } - - for (const auto &fingerprint : fingerprints) { - if (fingerprint.algorithm == "sha1") { - ui->lblSHA1->setText(QString::fromStdString(deskflow::formatSSLFingerprint(fingerprint.data))); - } - - if (fingerprint.algorithm == "sha256") { - ui->lblSHA256->setText(QString::fromStdString(deskflow::formatSSLFingerprintColumns(fingerprint.data))); - ui->lblSha256Art->setText(QString::fromStdString(deskflow::generateFingerprintArt(fingerprint.data))); - } - } - - QFont f = font(); - f.setFamilies({"Hack", "Liberation Mono", "Monospace", "Andale Mono"}); - f.setStyleHint(QFont::Monospace); - ui->lblSha256Art->setFont(f); - - if (ui->lblSHA1->text().isEmpty()) { - ui->sha1Frame->setVisible(false); - } - - if (ui->lblSHA256->text().isEmpty()) { - ui->sha256Frame->setVisible(false); - } - adjustSize(); -} - -FingerprintDialog::~FingerprintDialog() -{ - delete ui; + setFixedSize(size()); } diff --git a/src/apps/deskflow-gui/dialogs/FingerprintDialog.h b/src/apps/deskflow-gui/dialogs/FingerprintDialog.h index 3b5274296..597628b45 100644 --- a/src/apps/deskflow-gui/dialogs/FingerprintDialog.h +++ b/src/apps/deskflow-gui/dialogs/FingerprintDialog.h @@ -11,10 +11,6 @@ #include #include -namespace Ui { -class FingerprintDialog; -} - enum FingerprintDialogMode { Local, @@ -22,6 +18,9 @@ enum FingerprintDialogMode Server }; +class QLabel; +class FingerprintPreview; + class FingerprintDialog : public QDialog { Q_OBJECT @@ -31,8 +30,14 @@ public: QWidget *parent = nullptr, const QList &fingerprints = {}, FingerprintDialogMode mode = FingerprintDialogMode::Local ); - ~FingerprintDialog(); + ~FingerprintDialog() = default; + +signals: + void requestLocalPrintsDialog(); private: - Ui::FingerprintDialog *ui = nullptr; + QLabel *m_lblHeader = nullptr; + QLabel *m_lblFooter = nullptr; + FingerprintPreview *m_fingerprintPreview = nullptr; + QDialogButtonBox *m_buttonBox = nullptr; }; diff --git a/src/apps/deskflow-gui/dialogs/FingerprintDialog.ui b/src/apps/deskflow-gui/dialogs/FingerprintDialog.ui deleted file mode 100644 index e23ead0b8..000000000 --- a/src/apps/deskflow-gui/dialogs/FingerprintDialog.ui +++ /dev/null @@ -1,255 +0,0 @@ - - - FingerprintDialog - - - - - - - 0 - 0 - - - - - - - true - - - sha256Frame - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed - - - - 20 - 10 - - - - - - - - - 0 - 0 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Sunken - - - - - - - 0 - 0 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Sunken - - - - 6 - - - 6 - - - - - - 0 - 0 - - - - SHA1 - - - - - - - - 0 - 0 - - - - lblSHA1 - - - Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse - - - - - - - - - - - 0 - 0 - - - - QFrame::Shape::StyledPanel - - - QFrame::Shadow::Sunken - - - - 6 - - - 6 - - - - - - 0 - 0 - - - - SHA256 - - - - - - - - - TextLabel - - - Qt::AlignmentFlag::AlignHCenter|Qt::AlignmentFlag::AlignTop - - - Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse - - - - - - - sha ART - - - Qt::AlignmentFlag::AlignCenter - - - Qt::TextInteractionFlag::LinksAccessibleByMouse|Qt::TextInteractionFlag::TextSelectableByMouse - - - - - - - - - - - - - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::Fixed - - - - 20 - 10 - - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - QDialogButtonBox::StandardButton::Ok - - - - - - - - - buttonBox - rejected() - FingerprintDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - buttonBox - accepted() - FingerprintDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - diff --git a/src/apps/deskflow-gui/widgets/FingerprintPreview.cpp b/src/apps/deskflow-gui/widgets/FingerprintPreview.cpp new file mode 100644 index 000000000..8e8fdceb0 --- /dev/null +++ b/src/apps/deskflow-gui/widgets/FingerprintPreview.cpp @@ -0,0 +1,101 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#include "FingerprintPreview.h" + +#include +#include +#include + +#include + +FingerprintPreview::FingerprintPreview(QWidget *parent, const QList &fingerprints) + : QFrame(parent) +{ + setFrameShape(QFrame::StyledPanel); + setFrameStyle(QFrame::Sunken); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + QString sha1String; + QString sha256String; + QString sha256Art; + + for (const auto &fingerprint : fingerprints) { + if (fingerprint.algorithm == "sha1") { + sha1String = QString::fromStdString(deskflow::formatSSLFingerprint(fingerprint.data)); + } + + if (fingerprint.algorithm == "sha256") { + sha256String = QString::fromStdString(deskflow::formatSSLFingerprintColumns(fingerprint.data)); + sha256Art = QString::fromStdString(deskflow::generateFingerprintArt(fingerprint.data)); + } + } + + auto labelSha1 = new QLabel(QStringLiteral("SHA1:"), this); + labelSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + auto lblSha1 = new QLabel(sha1String, this); + lblSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + lblSha1->setTextInteractionFlags(Qt::TextSelectableByMouse); + + auto sha1Layout = new QHBoxLayout(); + sha1Layout->addWidget(labelSha1); + sha1Layout->addWidget(lblSha1); + + auto frameSha1 = new QFrame(this); + frameSha1->setFrameShape(QFrame::StyledPanel); + frameSha1->setFrameStyle(QFrame::Sunken); + frameSha1->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + frameSha1->setLayout(sha1Layout); + + auto labelSha256 = new QLabel(QStringLiteral("SHA256:"), this); + labelSha256->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + auto lblSha256String = new QLabel(sha256String, this); + lblSha256String->setAlignment(Qt::AlignTop | Qt::AlignHCenter); + lblSha256String->setTextInteractionFlags(Qt::TextSelectableByMouse); + + auto lblSha256Art = new QLabel(sha256Art, this); + lblSha256Art->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter); + lblSha256Art->setTextInteractionFlags(Qt::TextSelectableByMouse); + + QFont f = font(); + f.setFamilies({"Hack", "Liberation Mono", "Monospace", "Andale Mono"}); + f.setStyleHint(QFont::Monospace); + lblSha256Art->setFont(f); + + auto innersha256Layout = new QHBoxLayout(); + innersha256Layout->setContentsMargins(0, 0, 0, 0); + innersha256Layout->addWidget(lblSha256String); + innersha256Layout->addWidget(lblSha256Art); + + auto sha256Layout = new QVBoxLayout(); + sha256Layout->addWidget(labelSha256); + sha256Layout->addLayout(innersha256Layout); + + auto frameSha256 = new QFrame(this); + frameSha256->setFrameShape(QFrame::StyledPanel); + frameSha256->setFrameStyle(QFrame::Sunken); + frameSha256->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + frameSha256->setLayout(sha256Layout); + + auto layout = new QVBoxLayout(); + layout->addWidget(frameSha1); + layout->addWidget(frameSha256); + + setLayout(layout); + + if (sha1String.isEmpty()) { + frameSha1->setVisible(false); + } + + if (sha256String.isEmpty()) { + frameSha256->setVisible(false); + } + + adjustSize(); + setFixedSize(size()); +} diff --git a/src/apps/deskflow-gui/widgets/FingerprintPreview.h b/src/apps/deskflow-gui/widgets/FingerprintPreview.h new file mode 100644 index 000000000..c3fae57fa --- /dev/null +++ b/src/apps/deskflow-gui/widgets/FingerprintPreview.h @@ -0,0 +1,18 @@ +/* + * Deskflow -- mouse and keyboard sharing utility + * SPDX-FileCopyrightText: (C) 2025 Deskflow Developers + * SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception + */ + +#pragma once + +#include +#include + +class FingerprintPreview : public QFrame +{ + Q_OBJECT +public: + explicit FingerprintPreview(QWidget *parent, const QList &fingerprints = {}); + ~FingerprintPreview() = default; +}; diff --git a/src/apps/res/deskflow.qrc b/src/apps/res/deskflow.qrc index aee85a38e..b738022ec 100644 --- a/src/apps/res/deskflow.qrc +++ b/src/apps/res/deskflow.qrc @@ -13,6 +13,7 @@ icons/deskflow-dark/actions/22/edit-copy.svg icons/deskflow-dark/actions/22/document-open.svg icons/deskflow-dark/actions/22/document-save-as.svg + icons/deskflow-dark/actions/22/fingerprint.svg icons/deskflow-dark/actions/22/help-about.svg icons/deskflow-dark/actions/22/process-stop.svg icons/deskflow-dark/actions/22/system-run.svg @@ -23,6 +24,7 @@ icons/deskflow-dark/actions/24/document-open.svg icons/deskflow-dark/actions/24/document-save-as.svg icons/deskflow-dark/actions/24/edit-clear-all.svg + icons/deskflow-dark/actions/24/fingerprint.svg icons/deskflow-dark/actions/24/help-about.svg icons/deskflow-dark/actions/24/process-stop.svg icons/deskflow-dark/actions/24/system-run.svg @@ -65,6 +67,7 @@ icons/deskflow-light/actions/22/edit-copy.svg icons/deskflow-light/actions/22/document-open.svg icons/deskflow-light/actions/22/document-save-as.svg + icons/deskflow-light/actions/22/fingerprint.svg icons/deskflow-light/actions/22/help-about.svg icons/deskflow-light/actions/22/process-stop.svg icons/deskflow-light/actions/22/system-run.svg @@ -73,6 +76,7 @@ icons/deskflow-light/actions/24/configure.svg icons/deskflow-light/actions/24/edit-clear-all.svg icons/deskflow-light/actions/24/edit-copy.svg + icons/deskflow-light/actions/24/fingerprint.svg icons/deskflow-light/actions/24/document-open.svg icons/deskflow-light/actions/24/document-save-as.svg icons/deskflow-light/actions/24/help-about.svg diff --git a/src/apps/res/icons/deskflow-dark/actions/22/fingerprint.svg b/src/apps/res/icons/deskflow-dark/actions/22/fingerprint.svg new file mode 100644 index 000000000..1013bdaaa --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/22/fingerprint.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/apps/res/icons/deskflow-dark/actions/24/fingerprint.svg b/src/apps/res/icons/deskflow-dark/actions/24/fingerprint.svg new file mode 100644 index 000000000..36e83ae1d --- /dev/null +++ b/src/apps/res/icons/deskflow-dark/actions/24/fingerprint.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/22/fingerprint.svg b/src/apps/res/icons/deskflow-light/actions/22/fingerprint.svg new file mode 100644 index 000000000..6249c2256 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/22/fingerprint.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/src/apps/res/icons/deskflow-light/actions/24/fingerprint.svg b/src/apps/res/icons/deskflow-light/actions/24/fingerprint.svg new file mode 100644 index 000000000..99a6695e4 --- /dev/null +++ b/src/apps/res/icons/deskflow-light/actions/24/fingerprint.svg @@ -0,0 +1,12 @@ + + + + + + + +