From d2da13da2004154b68c991f62476d9ac5e19953d Mon Sep 17 00:00:00 2001 From: sforst Date: Mon, 7 Oct 2024 04:39:50 +0200 Subject: [PATCH] Support opening remote databases (#10896) * Use the import wizard to support opening a remote database --------- Co-authored-by: Jonathan White --- docs/topics/ImportExport.adoc | 16 ++++ share/translations/keepassxc_en.ts | 38 +++++++++ src/gui/DatabaseTabWidget.cpp | 92 ++++++++++++---------- src/gui/DatabaseTabWidget.h | 4 +- src/gui/wizard/ImportWizard.cpp | 5 ++ src/gui/wizard/ImportWizard.h | 15 +++- src/gui/wizard/ImportWizardPageReview.cpp | 55 +++++++++++++ src/gui/wizard/ImportWizardPageReview.h | 11 +++ src/gui/wizard/ImportWizardPageSelect.cpp | 66 +++++++++++++++- src/gui/wizard/ImportWizardPageSelect.h | 2 + src/gui/wizard/ImportWizardPageSelect.ui | 73 ++++++++++++++--- tests/data/SyncDatabase.kdbx | Bin 32286 -> 33070 bytes tests/gui/TestGui.cpp | 63 +++++++++++++-- tests/gui/TestGui.h | 1 + 14 files changed, 379 insertions(+), 62 deletions(-) diff --git a/docs/topics/ImportExport.adoc b/docs/topics/ImportExport.adoc index bcae4ce57..5786c2ab1 100644 --- a/docs/topics/ImportExport.adoc +++ b/docs/topics/ImportExport.adoc @@ -11,6 +11,7 @@ KeePassXC allows you to import external databases from the following options: * 1Password Vault (.opvault) * Bitwarden (.json) * KeePass 1 Database (.kdb) +* Remote database (.kdbx) To import any of these files, start KeePassXC and either click the `Import File` button on the welcome screen or use the menu Database > Import... to launch the Import Wizard. @@ -67,6 +68,21 @@ To import a KeePass 1 database file in KeePassXC, perform the following steps: 3. Click `Continue` to unlock and preview the import. Click `Done` to complete the import. +=== Importing Remote Database +Database files that are stored in a remote location can be imported or opened with KeePassXC if you provide a command to download the file from the remote location. + +To import (or temporarily open) a remote database file in KeePassXC, perform the following steps: + +1. Open the Import Wizard as shown above. Select the Remote Database option. + +2. Enter a command to download the remote database. If necessary, enter input that needs to be passed to the command. The command and/or input need a `{TEMP_DATABASE}` placeholder specified where the remote database is temporarily stored. + +3. Enter the password for your database and optionally provide a key file. + +4. Click `Continue` to unlock and preview the import. Click `Done` to complete the import. + +Opening without importing a remote database is possible by selecting Temporary Database in the Import Into section of the wizard. + == Exporting Databases KeePassXC supports multiple ways to export your database for transfer to another program or to print out and archive. diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 36de355aa..2ef44aa50 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -4490,6 +4490,14 @@ You can enable the DuckDuckGo website icon service in the security section of th Url + + Could not load key file. + + + + Could not open remote database. Password or key file may be incorrect. + + ImportWizardPageSelect @@ -4593,6 +4601,36 @@ You can enable the DuckDuckGo website icon service in the security section of th KeePass1 Database + + Temporary Database + + + + Command: + + + + e.g.: "sftp user@hostname" or "scp user@hostname:DatabaseOnRemote.kdbx {TEMP_DATABASE}" + + + + Input: + + + + Remote Database (.kdbx) + + + + e.g.: +get DatabaseOnRemote.kdbx {TEMP_DATABASE} +exit +--- +{TEMP_DATABASE} is used as placeholder to store the database in a temporary location +The command has to exit. In case of `sftp` as last commend `exit` has to be sent + + + KMessageWidget diff --git a/src/gui/DatabaseTabWidget.cpp b/src/gui/DatabaseTabWidget.cpp index b9b26d377..f5cfd70d8 100644 --- a/src/gui/DatabaseTabWidget.cpp +++ b/src/gui/DatabaseTabWidget.cpp @@ -35,13 +35,13 @@ #include "gui/osutils/macutils/MacUtils.h" #endif #include "gui/wizard/NewDatabaseWizard.h" -#include "wizard/ImportWizard.h" DatabaseTabWidget::DatabaseTabWidget(QWidget* parent) : QTabWidget(parent) , m_dbWidgetStateSync(new DatabaseWidgetStateSync(this)) , m_dbWidgetPendingLock(nullptr) , m_databaseOpenDialog(new DatabaseOpenDialog(this)) + , m_importWizard(nullptr) , m_databaseOpenInProgress(false) { auto* tabBar = new QTabBar(this); @@ -255,53 +255,65 @@ void DatabaseTabWidget::addDatabaseTab(DatabaseWidget* dbWidget, bool inBackgrou &DatabaseTabWidget::unlockDatabaseInDialogForSync); } -DatabaseWidget* DatabaseTabWidget::importFile() +void DatabaseTabWidget::importFile() { // Show the import wizard - QScopedPointer wizard(new ImportWizard(this)); - if (!wizard->exec()) { - return nullptr; - } + m_importWizard = new ImportWizard(this); - auto db = wizard->database(); - if (!db) { - // Import wizard was cancelled - return nullptr; - } - - auto importInto = wizard->importInto(); - if (importInto.first.isNull()) { - // Start the new database wizard with the imported database - auto newDb = execNewDatabaseWizard(); - if (newDb) { - // Merge the imported db into the new one - Merger merger(db.data(), newDb.data()); - merger.setSkipDatabaseCustomData(true); - merger.merge(); - // Show the new database - auto dbWidget = new DatabaseWidget(newDb, this); - addDatabaseTab(dbWidget); - newDb->markAsModified(); - return dbWidget; + connect(m_importWizard.data(), &QWizard::finished, [&](int result) { + if (result != QDialog::Accepted) { + return; } - } else { - for (int i = 0, c = count(); i < c; ++i) { - // Find the database and group to import into based on import wizard choice - auto dbWidget = databaseWidgetFromIndex(i); - if (!dbWidget->isLocked() && dbWidget->database()->uuid() == importInto.first) { - auto group = dbWidget->database()->rootGroup()->findGroupByUuid(importInto.second); - if (group) { - // Extract the root group from the import database - auto importGroup = db->setRootGroup(new Group()); - importGroup->setParent(group); - setCurrentIndex(i); - return dbWidget; + + auto db = m_importWizard->database(); + if (!db) { + // Import wizard was cancelled + return; + } + + switch (m_importWizard->importIntoType()) { + case ImportWizard::EXISTING_DATABASE: + for (int i = 0, c = count(); i < c; ++i) { + auto importInto = m_importWizard->importInto(); + // Find the database and group to import into based on import wizard choice + auto dbWidget = databaseWidgetFromIndex(i); + if (!dbWidget->isLocked() && dbWidget->database()->uuid() == importInto.first) { + auto group = dbWidget->database()->rootGroup()->findGroupByUuid(importInto.second); + if (group) { + // Extract the root group from the import database + auto importGroup = db->setRootGroup(new Group()); + importGroup->setParent(group); + setCurrentIndex(i); + return; + } } } + break; + case ImportWizard::TEMPORARY_DATABASE: { + // Use the already created database as temporary database + auto dbWidget = new DatabaseWidget(db, this); + addDatabaseTab(dbWidget); + return; } - } + default: + // Start the new database wizard with the imported database + auto newDb = execNewDatabaseWizard(); + if (newDb) { + // Merge the imported db into the new one + Merger merger(db.data(), newDb.data()); + merger.setSkipDatabaseCustomData(true); + merger.merge(); + // Show the new database + auto dbWidget = new DatabaseWidget(newDb, this); + addDatabaseTab(dbWidget); + newDb->markAsModified(); + return; + } + } + }); - return nullptr; + // use `open` instead of `exec`. `exec` should not be used, see https://doc.qt.io/qt-6/qdialog.html#exec + m_importWizard->show(); } void DatabaseTabWidget::mergeDatabase() diff --git a/src/gui/DatabaseTabWidget.h b/src/gui/DatabaseTabWidget.h index aa8542dd9..eb5e06b30 100644 --- a/src/gui/DatabaseTabWidget.h +++ b/src/gui/DatabaseTabWidget.h @@ -21,6 +21,7 @@ #include "DatabaseOpenDialog.h" #include "config-keepassx.h" #include "gui/MessageWidget.h" +#include "wizard/ImportWizard.h" #include #include @@ -64,7 +65,7 @@ public slots: DatabaseWidget* newDatabase(); void openDatabase(); void mergeDatabase(); - DatabaseWidget* importFile(); + void importFile(); bool saveDatabase(int index = -1); bool saveDatabaseAs(int index = -1); bool saveDatabaseBackup(int index = -1); @@ -123,6 +124,7 @@ private: QPointer m_dbWidgetStateSync; QPointer m_dbWidgetPendingLock; QPointer m_databaseOpenDialog; + QPointer m_importWizard; QTimer m_lockDelayTimer; bool m_databaseOpenInProgress; }; diff --git a/src/gui/wizard/ImportWizard.cpp b/src/gui/wizard/ImportWizard.cpp index 05fdbfe38..ff3769347 100644 --- a/src/gui/wizard/ImportWizard.cpp +++ b/src/gui/wizard/ImportWizard.cpp @@ -69,6 +69,11 @@ bool ImportWizard::validateCurrentPage() return ret; } +ImportWizard::ImportIntoType ImportWizard::importIntoType() +{ + return static_cast(field("ImportIntoType").toInt()); +} + QPair ImportWizard::importInto() { auto list = field("ImportInto").toList(); diff --git a/src/gui/wizard/ImportWizard.h b/src/gui/wizard/ImportWizard.h index b7e9de68d..95bf8b998 100644 --- a/src/gui/wizard/ImportWizard.h +++ b/src/gui/wizard/ImportWizard.h @@ -19,6 +19,7 @@ #define KEEPASSXC_IMPORTWIZARD_H #include +#include #include class Database; @@ -39,7 +40,6 @@ public: bool validateCurrentPage() override; QSharedPointer database(); - QPair importInto(); enum ImportType { @@ -48,9 +48,20 @@ public: IMPORT_OPVAULT, IMPORT_OPUX, IMPORT_BITWARDEN, - IMPORT_KEEPASS1 + IMPORT_KEEPASS1, + IMPORT_REMOTE, }; + enum ImportIntoType + { + NEW_DATABASE = 1, + EXISTING_DATABASE, + TEMPORARY_DATABASE, + }; + + ImportWizard::ImportIntoType importIntoType(); + QPair importInto(); + private: QSharedPointer m_db; QPointer m_pageSelect; diff --git a/src/gui/wizard/ImportWizardPageReview.cpp b/src/gui/wizard/ImportWizardPageReview.cpp index 2cb56791b..55492a67f 100644 --- a/src/gui/wizard/ImportWizardPageReview.cpp +++ b/src/gui/wizard/ImportWizardPageReview.cpp @@ -27,14 +27,23 @@ #include "gui/csvImport/CsvImportWidget.h" #include "gui/wizard/ImportWizard.h" +#include "cli/Utils.h" +#include "keys/FileKey.h" +#include "keys/PasswordKey.h" + #include #include #include #include +#include "gui/remote/RemoteSettings.h" + +struct RemoteParams; + ImportWizardPageReview::ImportWizardPageReview(QWidget* parent) : QWizardPage(parent) , m_ui(new Ui::ImportWizardPageReview) + , m_remoteHandler(new RemoteHandler(this)) { } @@ -80,6 +89,12 @@ void ImportWizardPageReview::initializePage() m_db = importBitwarden(filename, field("ImportPassword").toString()); setupDatabasePreview(); break; + case ImportWizard::IMPORT_REMOTE: + m_db = importRemote(field("DownloadCommand").toString(), + field("DownloadInput").toString(), + field("ImportPassword").toString(), + field("ImportKeyFile").toString()); + setupDatabasePreview(); default: break; } @@ -200,3 +215,43 @@ ImportWizardPageReview::importKeePass1(const QString& filename, const QString& p return db; } + +QSharedPointer ImportWizardPageReview::importRemote(const QString& downloadCommand, + const QString& downloadInput, + const QString& password, + const QString& keyfile) +{ + auto* params = new RemoteParams(); + params->downloadCommand = downloadCommand; + params->downloadInput = downloadInput; + + auto result = m_remoteHandler->download(params); + + if (!result.success) { + m_ui->messageWidget->showMessage(result.errorMessage, KMessageWidget::Error, -1); + } + + auto key = QSharedPointer::create(); + + if (!password.isEmpty()) { + key->addKey(QSharedPointer::create(password)); + } + if (!keyfile.isEmpty()) { + QSharedPointer fileKey = QSharedPointer::create(); + if (Utils::loadFileKey(keyfile, fileKey)) { + key->addKey(fileKey); + } else { + m_ui->messageWidget->showMessage(tr("Could not load key file."), KMessageWidget::Error, -1); + } + } + + QString error; + QSharedPointer remoteDb = QSharedPointer::create(); + remoteDb->markAsTemporaryDatabase(); + if (!remoteDb->open(result.filePath, key, &error)) { + m_ui->messageWidget->showMessage( + tr("Could not open remote database. Password or key file may be incorrect."), KMessageWidget::Error, -1); + } + + return remoteDb; +} diff --git a/src/gui/wizard/ImportWizardPageReview.h b/src/gui/wizard/ImportWizardPageReview.h index 87f501c85..c1df3efff 100644 --- a/src/gui/wizard/ImportWizardPageReview.h +++ b/src/gui/wizard/ImportWizardPageReview.h @@ -21,6 +21,12 @@ #include #include +#include +#include +#include + +#include "../remote/RemoteHandler.h" + class CsvImportWidget; class Database; namespace Ui @@ -48,6 +54,10 @@ private: QSharedPointer importBitwarden(const QString& filename, const QString& password); QSharedPointer importOPVault(const QString& filename, const QString& password); QSharedPointer importKeePass1(const QString& filename, const QString& password, const QString& keyfile); + QSharedPointer importRemote(const QString& downloadCommand, + const QString& downloadInput, + const QString& password, + const QString& keyfile); void setupDatabasePreview(); @@ -55,6 +65,7 @@ private: QSharedPointer m_db; QPointer m_csvWidget; + QPointer m_remoteHandler; }; #endif diff --git a/src/gui/wizard/ImportWizardPageSelect.cpp b/src/gui/wizard/ImportWizardPageSelect.cpp index 43b0e8f2a..e7bdacc9f 100644 --- a/src/gui/wizard/ImportWizardPageSelect.cpp +++ b/src/gui/wizard/ImportWizardPageSelect.cpp @@ -25,6 +25,8 @@ #include "gui/Icons.h" #include "gui/MainWindow.h" +#include + ImportWizardPageSelect::ImportWizardPageSelect(QWidget* parent) : QWizardPage(parent) , m_ui(new Ui::ImportWizardPageSelect()) @@ -36,12 +38,14 @@ ImportWizardPageSelect::ImportWizardPageSelect(QWidget* parent) new QListWidgetItem(icons()->icon("onepassword"), tr("1Password Vault (.opvault)"), m_ui->importTypeList); new QListWidgetItem(icons()->icon("bitwarden"), tr("Bitwarden (.json)"), m_ui->importTypeList); new QListWidgetItem(icons()->icon("object-locked"), tr("KeePass 1 Database (.kdb)"), m_ui->importTypeList); + new QListWidgetItem(icons()->icon("web"), tr("Remote Database (.kdbx)"), m_ui->importTypeList); m_ui->importTypeList->item(0)->setData(Qt::UserRole, ImportWizard::IMPORT_CSV); m_ui->importTypeList->item(1)->setData(Qt::UserRole, ImportWizard::IMPORT_OPUX); m_ui->importTypeList->item(2)->setData(Qt::UserRole, ImportWizard::IMPORT_OPVAULT); m_ui->importTypeList->item(3)->setData(Qt::UserRole, ImportWizard::IMPORT_BITWARDEN); m_ui->importTypeList->item(4)->setData(Qt::UserRole, ImportWizard::IMPORT_KEEPASS1); + m_ui->importTypeList->item(5)->setData(Qt::UserRole, ImportWizard::IMPORT_REMOTE); connect(m_ui->importTypeList, &QListWidget::currentItemChanged, this, &ImportWizardPageSelect::itemSelected); m_ui->importTypeList->setCurrentRow(0); @@ -54,11 +58,22 @@ ImportWizardPageSelect::ImportWizardPageSelect(QWidget* parent) updateDatabaseChoices(); + m_ui->downloadCommandHelpButton->setIcon(icons()->icon("system-help")); + connect(m_ui->downloadCommandHelpButton, &QToolButton::clicked, this, [] { + QDesktopServices::openUrl(QUrl("https://keepassxc.org/docs/KeePassXC_UserGuide#_remote_database_support")); + }); + + connect(m_ui->importFileEdit, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); + connect(m_ui->downloadCommand, &QLineEdit::textChanged, this, &QWizardPage::completeChanged); + registerField("ImportType", this); - registerField("ImportFile*", m_ui->importFileEdit); - registerField("ImportInto", m_ui->importIntoLabel); + registerField("ImportFile", m_ui->importFileEdit); + registerField("ImportIntoType", m_ui->importIntoGroupBox); // This is intentional + registerField("ImportInto", m_ui->importIntoLabel); // This is intentional registerField("ImportPassword", m_ui->passwordEdit, "text", "textChanged"); registerField("ImportKeyFile", m_ui->keyFileEdit); + registerField("DownloadCommand", m_ui->downloadCommand); + registerField("DownloadInput", m_ui->downloadCommandInput, "plainText", "textChanged"); } ImportWizardPageSelect::~ImportWizardPageSelect() @@ -77,14 +92,27 @@ bool ImportWizardPageSelect::validatePage() if (m_ui->existingDatabaseChoice->currentIndex() == -1) { return false; } + setField("ImportIntoType", ImportWizard::EXISTING_DATABASE); setField("ImportInto", m_ui->existingDatabaseChoice->currentData()); + } else if (m_ui->temporaryDatabaseRadio->isChecked()) { + setField("ImportIntoType", ImportWizard::TEMPORARY_DATABASE); + setField("ImportInto", {}); } else { + setField("ImportIntoType", ImportWizard::NEW_DATABASE); setField("ImportInto", {}); } return true; } +bool ImportWizardPageSelect::isComplete() const +{ + if (field("ImportType").toInt() == ImportWizard::IMPORT_REMOTE) { + return !field("DownloadCommand").toString().isEmpty(); + } + return !field("ImportFile").toString().isEmpty(); +} + void ImportWizardPageSelect::itemSelected(QListWidgetItem* current, QListWidgetItem* previous) { Q_UNUSED(previous) @@ -105,15 +133,22 @@ void ImportWizardPageSelect::itemSelected(QListWidgetItem* current, QListWidgetI case ImportWizard::IMPORT_CSV: case ImportWizard::IMPORT_OPUX: setCredentialState(false); + setDownloadCommand(false); break; // Password may be required case ImportWizard::IMPORT_BITWARDEN: case ImportWizard::IMPORT_OPVAULT: setCredentialState(true); + setDownloadCommand(false); break; // Password and/or Key File may be required case ImportWizard::IMPORT_KEEPASS1: setCredentialState(true, true); + setDownloadCommand(false); + break; + case ImportWizard::IMPORT_REMOTE: + setCredentialState(true, true); + setDownloadCommand(true); break; default: Q_ASSERT(false); @@ -228,6 +263,33 @@ void ImportWizardPageSelect::setCredentialState(bool passwordEnabled, bool keyFi } } +void ImportWizardPageSelect::setDownloadCommand(bool downloadCommandEnabled) +{ + bool downloadCommandStateChanged = m_ui->downloadCommandLabel->isVisible() != downloadCommandEnabled; + m_ui->downloadCommandLabel->setVisible(downloadCommandEnabled); + m_ui->downloadCommand->setVisible(downloadCommandEnabled); + m_ui->downloadCommandInputLabel->setVisible(downloadCommandEnabled); + m_ui->downloadCommandInput->setVisible(downloadCommandEnabled); + m_ui->downloadCommandHelpButton->setVisible(downloadCommandEnabled); + + m_ui->temporaryDatabaseRadio->setVisible(downloadCommandEnabled); + + m_ui->importFileLabel->setVisible(!downloadCommandEnabled); + m_ui->importFileEdit->setVisible(!downloadCommandEnabled); + m_ui->importFileButton->setVisible(!downloadCommandEnabled); + + // Workaround Qt bug where the wizard window is not updated when the internal layout changes + if (window()) { + int height = window()->height(); + if (downloadCommandStateChanged) { + auto diff = m_ui->downloadCommand->height() + m_ui->downloadCommandInput->height() + + m_ui->temporaryDatabaseRadio->height() + m_ui->inputFields->layout()->spacing(); + height += downloadCommandEnabled ? diff : -diff; + } + window()->resize(window()->width(), height); + } +} + QString ImportWizardPageSelect::importFileFilter() { switch (field("ImportType").toInt()) { diff --git a/src/gui/wizard/ImportWizardPageSelect.h b/src/gui/wizard/ImportWizardPageSelect.h index 029865a56..5c4024ea5 100644 --- a/src/gui/wizard/ImportWizardPageSelect.h +++ b/src/gui/wizard/ImportWizardPageSelect.h @@ -39,6 +39,7 @@ public: void initializePage() override; bool validatePage() override; + bool isComplete() const override; private slots: void itemSelected(QListWidgetItem* current, QListWidgetItem* previous); @@ -49,6 +50,7 @@ private slots: private: QString importFileFilter(); void setCredentialState(bool passwordEnabled, bool keyFileEnable = false); + void setDownloadCommand(bool downloadCommandEnabled); QScopedPointer m_ui; }; diff --git a/src/gui/wizard/ImportWizardPageSelect.ui b/src/gui/wizard/ImportWizardPageSelect.ui index 6a7c8adad..ca37fec71 100644 --- a/src/gui/wizard/ImportWizardPageSelect.ui +++ b/src/gui/wizard/ImportWizardPageSelect.ui @@ -94,14 +94,14 @@ QLayout::SetMinimumSize - + Import File: - + @@ -115,24 +115,24 @@ - + Password: - + - + Key File: - + @@ -146,7 +146,7 @@ - + Qt::Vertical @@ -162,7 +162,7 @@ - + Import Into: @@ -172,7 +172,7 @@ - + @@ -239,9 +239,64 @@ + + + + Temporary Database + + + + + + + Command: + + + + + + + + + e.g.: "sftp user@hostname" or "scp user@hostname:DatabaseOnRemote.kdbx {TEMP_DATABASE}" + + + + + + + + + + + + + + + + Input: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + e.g.: +get DatabaseOnRemote.kdbx {TEMP_DATABASE} +exit +--- +{TEMP_DATABASE} is used as placeholder to store the database in a temporary location +The command has to exit. In case of `sftp` as last commend `exit` has to be sent + + + + diff --git a/tests/data/SyncDatabase.kdbx b/tests/data/SyncDatabase.kdbx index f72e6fb9ef638a3820874627a11af6a97d296895..1a8ad9375af3d1b94a528f9f8011210d89b5ba7f 100644 GIT binary patch literal 33070 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 literal 32286 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 #include #include +#include #include #include @@ -397,14 +398,10 @@ void TestGui::prepareAndTriggerRemoteSync(const QString& sourceToSync) QVERIFY(saveSettingsButton != nullptr); QTest::mouseClick(saveSettingsButton, Qt::LeftButton); - // find and click dialog OK button - auto buttons = dbSettingsDialog->findChild()->findChildren(); - for (QPushButton* b : buttons) { - if (b->text() == "OK") { - QTest::mouseClick(b, Qt::LeftButton); - break; - } - } + auto okButton = dbSettingsDialog->findChild("buttonBox")->button(QDialogButtonBox::Ok); + QVERIFY(okButton); + QTest::mouseClick(okButton, Qt::LeftButton); + QTRY_COMPARE(m_dbWidget->getRemoteParams().size(), 1); // trigger aboutToShow to create remote actions @@ -477,6 +474,56 @@ void TestGui::testRemoteSyncDatabaseRequiresPassword() QCOMPARE(m_db->rootGroup()->findChildByName("General")->entries().size(), 1); } +void TestGui::testOpenRemoteDatabase() +{ + // close current database + cleanup(); + + QString sourceToSync = "sftp user@server:Database.kdbx"; + RemoteHandler::setRemoteProcessFunc([sourceToSync](QObject* parent) { + return QScopedPointer( + new MockRemoteProcess(parent, QString(KEEPASSX_TEST_DATA_DIR).append("/SyncDatabase.kdbx"))); + }); + auto* openRemoteButton = QApplication::activeWindow()->findChild("buttonImport"); + QVERIFY(openRemoteButton); + QVERIFY(openRemoteButton->isVisible()); + QTest::mouseClick(openRemoteButton, Qt::LeftButton); + QApplication::processEvents(); + + TEST_MODAL_NO_WAIT( + ImportWizard * wizard; QTRY_VERIFY(wizard = m_tabWidget->findChild()); + + auto* importTypeList = wizard->currentPage()->findChild("importTypeList"); + QVERIFY(importTypeList); + importTypeList->scrollToBottom(); + + QListWidgetItem* remoteOption = importTypeList->item(importTypeList->count() - 1); + QRect remoteOptionRect = importTypeList->visualItemRect(remoteOption); + QTest::mouseClick(importTypeList->viewport(), Qt::LeftButton, nullptr, remoteOptionRect.center()); + + auto* downloadCommandEdit = wizard->currentPage()->findChild("downloadCommand"); + QVERIFY(downloadCommandEdit); + QTest::keyClicks(downloadCommandEdit, sourceToSync); + + auto* temporaryDatabaseRadio = wizard->currentPage()->findChild("temporaryDatabaseRadio"); + QVERIFY(temporaryDatabaseRadio); + QTest::mouseClick(temporaryDatabaseRadio, Qt::LeftButton); + + auto* passwordEdit = wizard->currentPage()->findChild("passwordEdit"); + QVERIFY(passwordEdit); + QTest::keyClicks(passwordEdit, "a"); + QTest::keyClick(passwordEdit, Qt::Key_Enter); + + QApplication::processEvents(); + + QVERIFY(wizard->currentPage()->findChildren().count() > 0); + + QTest::keyClick(passwordEdit, Qt::Key_Enter);); + + // remote database has been opened + QTRY_COMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("SyncDatabase [Temporary]")); +} + void TestGui::testAutoreloadDatabase() { config()->set(Config::AutoReloadOnChange, false); diff --git a/tests/gui/TestGui.h b/tests/gui/TestGui.h index 70ff5dfc5..720e3e2a6 100644 --- a/tests/gui/TestGui.h +++ b/tests/gui/TestGui.h @@ -42,6 +42,7 @@ private slots: void testMergeDatabase(); void testRemoteSyncDatabaseSameKey(); void testRemoteSyncDatabaseRequiresPassword(); + void testOpenRemoteDatabase(); void testAutoreloadDatabase(); void testTabs(); void testEditEntry();