From 851a13c11bf0db4f92f4d6447653049fcd358d67 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Thu, 31 Oct 2019 14:26:04 -0700 Subject: [PATCH] Handle incorrect passwords properly with export Fixes !5 --- src/controller.cpp | 6 +- src/mainwindow.cpp | 170 +++++++++++++++++++++------------------------ src/privkey.ui | 2 +- src/settings.h | 5 +- 4 files changed, 86 insertions(+), 97 deletions(-) diff --git a/src/controller.cpp b/src/controller.cpp index 004b545..d482f38 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -455,12 +455,16 @@ void Controller::unlockIfEncrypted(std::function cb, std::functiontr("Your wallet is encrypted.\nPlease enter your wallet password"), QLineEdit::Password); if (password.isEmpty()) { + QMessageBox::critical(main, main->tr("Wallet Decryption Failed"), + main->tr("Please enter a valid password"), + QMessageBox::Ok + ); error(); return; } zrpc->unlockWallet(password, [=](json reply) { - if (isJsonSuccess(reply)) { + if (isJsonResultSuccess(reply)) { cb(); // Refresh the wallet so the encryption status is now in sync. diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4fdd3db..6d40796 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -263,10 +263,10 @@ void MainWindow::encryptWallet() { if (d.exec() == QDialog::Accepted) { rpc->encryptWallet(ed.txtPassword->text(), [=](json res) { - if (isJsonSuccess(res)) { + if (isJsonResultSuccess(res)) { // Save the wallet rpc->saveWallet([=] (json reply) { - if (isJsonSuccess(reply)) { + if (isJsonResultSuccess(reply)) { QMessageBox::information(this, tr("Wallet Encrypted"), tr("Your wallet was successfully encrypted! The password will be needed to send funds or export private keys."), QMessageBox::Ok @@ -314,10 +314,10 @@ void MainWindow::removeWalletEncryption() { } rpc->removeWalletEncryption(password, [=] (json res) { - if (isJsonSuccess(res)) { + if (isJsonResultSuccess(res)) { // Save the wallet rpc->saveWallet([=] (json reply) { - if(isJsonSuccess(reply)) { + if(isJsonResultSuccess(reply)) { QMessageBox::information(this, tr("Wallet Encryption Removed"), tr("Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys."), QMessageBox::Ok @@ -654,54 +654,47 @@ void MainWindow::exportSeed() { if (!rpc->getConnection()) return; - QDialog d(this); - Ui_PrivKey pui; - pui.setupUi(&d); - // Make the window big by default - auto ps = this->geometry(); - QMargins margin = QMargins() + 50; - d.setGeometry(ps.marginsRemoved(margin)); - - Settings::saveRestore(&d); - - pui.privKeyTxt->setPlainText(tr("This might take several minutes. Loading...")); - pui.privKeyTxt->setReadOnly(true); - pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap); - - pui.helpLbl->setText(tr("This is your wallet seed. Please back it up carefully and safely.")); - - // Disable the save button until it finishes loading - pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); - pui.buttonBox->button(QDialogButtonBox::Ok)->setVisible(false); - - // Wire up save button - QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () { - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), - "zcash-seed.txt"); - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly)) { - QMessageBox::information(this, tr("Unable to open file"), file.errorString()); - return; - } - QTextStream out(&file); - out << pui.privKeyTxt->toPlainText(); - }); rpc->fetchSeed([=](json reply) { - if (isJsonError(reply)) { - pui.privKeyTxt->setPlainText(tr("Error loading wallet seed: ") + QString::fromStdString(reply["error"])); - pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); - + if (isJsonError(reply)) { return; } + + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); + + // Make the window big by default + auto ps = this->geometry(); + QMargins margin = QMargins() + 50; + d.setGeometry(ps.marginsRemoved(margin)); + + Settings::saveRestore(&d); + pui.privKeyTxt->setReadOnly(true); + pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap); pui.privKeyTxt->setPlainText(QString::fromStdString(reply.dump())); + + pui.helpLbl->setText(tr("This is your wallet seed. Please back it up carefully and safely.")); + + // Wire up save button + QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), + "zcash-seed.txt"); + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::information(this, tr("Unable to open file"), file.errorString()); + return; + } + QTextStream out(&file); + out << pui.privKeyTxt->toPlainText(); + }); + pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true); + + d.exec(); }); - - - d.exec(); } void MainWindow::exportAllKeys() { @@ -714,57 +707,51 @@ void MainWindow::exportKeys(QString addr) { bool allKeys = addr.isEmpty() ? true : false; - QDialog d(this); - Ui_PrivKey pui; - pui.setupUi(&d); - - // Make the window big by default - auto ps = this->geometry(); - QMargins margin = QMargins() + 50; - d.setGeometry(ps.marginsRemoved(margin)); - - Settings::saveRestore(&d); - - pui.privKeyTxt->setPlainText(tr("This might take several minutes. Loading...")); - pui.privKeyTxt->setReadOnly(true); - pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap); - - if (allKeys) - pui.helpLbl->setText(tr("These are all the private keys for all the addresses in your wallet")); - else - pui.helpLbl->setText(tr("Private key for ") + addr); - - // Disable the save button until it finishes loading - pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); - pui.buttonBox->button(QDialogButtonBox::Ok)->setVisible(false); - - // Wire up save button - QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () { - QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), - allKeys ? "zcash-all-privatekeys.txt" : "zcash-privatekey.txt"); - QFile file(fileName); - if (!file.open(QIODevice::WriteOnly)) { - QMessageBox::information(this, tr("Unable to open file"), file.errorString()); - return; - } - QTextStream out(&file); - out << pui.privKeyTxt->toPlainText(); - }); - - // Call the API - auto isDialogAlive = std::make_shared(true); - auto fnUpdateUIWithKeys = [=](json reply) { - // Check to see if we are still showing. - if (! *(isDialogAlive.get()) ) return; + if (isJsonError(reply)) { + return; + } if (reply.is_discarded() || !reply.is_array()) { - pui.privKeyTxt->setPlainText(tr("Error loading private keys: ") + QString::fromStdString(reply.dump())); - pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); - + QMessageBox::critical(this, tr("Error getting private keys"), + tr("Error loading private keys: ") + QString::fromStdString(reply.dump()), + QMessageBox::Ok); return; } + + QDialog d(this); + Ui_PrivKey pui; + pui.setupUi(&d); + // Make the window big by default + auto ps = this->geometry(); + QMargins margin = QMargins() + 50; + d.setGeometry(ps.marginsRemoved(margin)); + + Settings::saveRestore(&d); + + pui.privKeyTxt->setReadOnly(true); + pui.privKeyTxt->setLineWrapMode(QPlainTextEdit::LineWrapMode::NoWrap); + + if (allKeys) + pui.helpLbl->setText(tr("These are all the private keys for all the addresses in your wallet")); + else + pui.helpLbl->setText(tr("Private key for ") + addr); + + + // Wire up save button + QObject::connect(pui.buttonBox->button(QDialogButtonBox::Save), &QPushButton::clicked, [=] () { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), + allKeys ? "zcash-all-privatekeys.txt" : "zcash-privatekey.txt"); + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) { + QMessageBox::information(this, tr("Unable to open file"), file.errorString()); + return; + } + QTextStream out(&file); + out << pui.privKeyTxt->toPlainText(); + }); + QString allKeysTxt; for (auto i : reply.get()) { allKeysTxt = allKeysTxt % QString::fromStdString(i["private_key"]) % " # addr=" % QString::fromStdString(i["address"]) % "\n"; @@ -772,6 +759,8 @@ void MainWindow::exportKeys(QString addr) { pui.privKeyTxt->setPlainText(allKeysTxt); pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true); + + d.exec(); }; if (allKeys) { @@ -779,10 +768,7 @@ void MainWindow::exportKeys(QString addr) { } else { rpc->fetchPrivKey(addr, fnUpdateUIWithKeys); - } - - d.exec(); - *isDialogAlive = false; + } } void MainWindow::setupBalancesTab() { diff --git a/src/privkey.ui b/src/privkey.ui index 57bdb16..ffdb89c 100644 --- a/src/privkey.ui +++ b/src/privkey.ui @@ -27,7 +27,7 @@ Qt::Horizontal - QDialogButtonBox::Close|QDialogButtonBox::Ok|QDialogButtonBox::Save + QDialogButtonBox::Close|QDialogButtonBox::Save diff --git a/src/settings.h b/src/settings.h index d60619d..d2cbfbf 100644 --- a/src/settings.h +++ b/src/settings.h @@ -122,14 +122,13 @@ private: }; -inline bool isJsonSuccess(const json& res) { +inline bool isJsonResultSuccess(const json& res) { return res.find("result") != res.end() && QString::fromStdString(res["result"].get()) == "success"; } inline bool isJsonError(const json& res) { - return res.find("result") != res.end() && - QString::fromStdString(res["result"].get()) == "error"; + return res.find("error") != res.end(); }