Handle incorrect passwords properly with export

Fixes !5
This commit is contained in:
Aditya Kulkarni
2019-10-31 14:26:04 -07:00
parent 0d5ea2f5a5
commit 851a13c11b
4 changed files with 87 additions and 98 deletions

View File

@@ -455,12 +455,16 @@ void Controller::unlockIfEncrypted(std::function<void(void)> cb, std::function<v
main->tr("Your wallet is encrypted.\nPlease enter your wallet password"), QLineEdit::Password); main->tr("Your wallet is encrypted.\nPlease enter your wallet password"), QLineEdit::Password);
if (password.isEmpty()) { if (password.isEmpty()) {
QMessageBox::critical(main, main->tr("Wallet Decryption Failed"),
main->tr("Please enter a valid password"),
QMessageBox::Ok
);
error(); error();
return; return;
} }
zrpc->unlockWallet(password, [=](json reply) { zrpc->unlockWallet(password, [=](json reply) {
if (isJsonSuccess(reply)) { if (isJsonResultSuccess(reply)) {
cb(); cb();
// Refresh the wallet so the encryption status is now in sync. // Refresh the wallet so the encryption status is now in sync.

View File

@@ -263,10 +263,10 @@ void MainWindow::encryptWallet() {
if (d.exec() == QDialog::Accepted) { if (d.exec() == QDialog::Accepted) {
rpc->encryptWallet(ed.txtPassword->text(), [=](json res) { rpc->encryptWallet(ed.txtPassword->text(), [=](json res) {
if (isJsonSuccess(res)) { if (isJsonResultSuccess(res)) {
// Save the wallet // Save the wallet
rpc->saveWallet([=] (json reply) { rpc->saveWallet([=] (json reply) {
if (isJsonSuccess(reply)) { if (isJsonResultSuccess(reply)) {
QMessageBox::information(this, tr("Wallet Encrypted"), QMessageBox::information(this, tr("Wallet Encrypted"),
tr("Your wallet was successfully encrypted! The password will be needed to send funds or export private keys."), tr("Your wallet was successfully encrypted! The password will be needed to send funds or export private keys."),
QMessageBox::Ok QMessageBox::Ok
@@ -314,10 +314,10 @@ void MainWindow::removeWalletEncryption() {
} }
rpc->removeWalletEncryption(password, [=] (json res) { rpc->removeWalletEncryption(password, [=] (json res) {
if (isJsonSuccess(res)) { if (isJsonResultSuccess(res)) {
// Save the wallet // Save the wallet
rpc->saveWallet([=] (json reply) { rpc->saveWallet([=] (json reply) {
if(isJsonSuccess(reply)) { if(isJsonResultSuccess(reply)) {
QMessageBox::information(this, tr("Wallet Encryption Removed"), 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."), tr("Your wallet was successfully decrypted! You will no longer need a password to send funds or export private keys."),
QMessageBox::Ok QMessageBox::Ok
@@ -654,54 +654,47 @@ void MainWindow::exportSeed() {
if (!rpc->getConnection()) if (!rpc->getConnection())
return; 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) { rpc->fetchSeed([=](json reply) {
if (isJsonError(reply)) { if (isJsonError(reply)) {
pui.privKeyTxt->setPlainText(tr("Error loading wallet seed: ") + QString::fromStdString(reply["error"]));
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false);
return; 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.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); pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
d.exec();
}); });
d.exec();
} }
void MainWindow::exportAllKeys() { void MainWindow::exportAllKeys() {
@@ -714,57 +707,51 @@ void MainWindow::exportKeys(QString addr) {
bool allKeys = addr.isEmpty() ? true : false; bool allKeys = addr.isEmpty() ? true : false;
QDialog d(this); auto fnUpdateUIWithKeys = [=](json reply) {
Ui_PrivKey pui; if (isJsonError(reply)) {
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; return;
} }
QTextStream out(&file);
out << pui.privKeyTxt->toPlainText();
});
// Call the API
auto isDialogAlive = std::make_shared<bool>(true);
auto fnUpdateUIWithKeys = [=](json reply) {
// Check to see if we are still showing.
if (! *(isDialogAlive.get()) ) return;
if (reply.is_discarded() || !reply.is_array()) { if (reply.is_discarded() || !reply.is_array()) {
pui.privKeyTxt->setPlainText(tr("Error loading private keys: ") + QString::fromStdString(reply.dump())); QMessageBox::critical(this, tr("Error getting private keys"),
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); tr("Error loading private keys: ") + QString::fromStdString(reply.dump()),
QMessageBox::Ok);
return; 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; QString allKeysTxt;
for (auto i : reply.get<json::array_t>()) { for (auto i : reply.get<json::array_t>()) {
allKeysTxt = allKeysTxt % QString::fromStdString(i["private_key"]) % " # addr=" % QString::fromStdString(i["address"]) % "\n"; 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.privKeyTxt->setPlainText(allKeysTxt);
pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true); pui.buttonBox->button(QDialogButtonBox::Save)->setEnabled(true);
d.exec();
}; };
if (allKeys) { if (allKeys) {
@@ -780,9 +769,6 @@ void MainWindow::exportKeys(QString addr) {
else { else {
rpc->fetchPrivKey(addr, fnUpdateUIWithKeys); rpc->fetchPrivKey(addr, fnUpdateUIWithKeys);
} }
d.exec();
*isDialogAlive = false;
} }
void MainWindow::setupBalancesTab() { void MainWindow::setupBalancesTab() {

View File

@@ -27,7 +27,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok|QDialogButtonBox::Save</set> <set>QDialogButtonBox::Close|QDialogButtonBox::Save</set>
</property> </property>
</widget> </widget>
</item> </item>

View File

@@ -122,14 +122,13 @@ private:
}; };
inline bool isJsonSuccess(const json& res) { inline bool isJsonResultSuccess(const json& res) {
return res.find("result") != res.end() && return res.find("result") != res.end() &&
QString::fromStdString(res["result"].get<json::string_t>()) == "success"; QString::fromStdString(res["result"].get<json::string_t>()) == "success";
} }
inline bool isJsonError(const json& res) { inline bool isJsonError(const json& res) {
return res.find("result") != res.end() && return res.find("error") != res.end();
QString::fromStdString(res["result"].get<json::string_t>()) == "error";
} }