#
#
# add_file "res/forms/dialogs/change_key_password.ui"
# content [241cbef3ad9e2bad992bef55520c828ab8abd9dd]
#
# add_file "src/view/dialogs/ChangeKeyPassword.cpp"
# content [9b1251e7a8547a9ad74274a4b8254bf91bf94943]
#
# add_file "src/view/dialogs/ChangeKeyPassword.h"
# content [2a6c49b172801183406df48c4caee9fc0ee268af]
#
# patch "NEWS"
# from [7b8445f0080d5a63d84d86cdaa5df474ac6bc126]
# to [c9184fa1e0316e8b89728cf6824c69557d9e37c2]
#
# patch "guitone.pro"
# from [427722d346990785a3b3598c7bc49d40f606c179]
# to [8819a394eeff1b31d1077696920bf2397365d130]
#
# patch "src/view/dialogs/DatabaseDialogManager.cpp"
# from [114836269d5a2ee7c9d086efdda82d69728f79b6]
# to [2cc6cb87b8c1d5661f183fa98e2e9b251c63229c]
#
# patch "src/view/dialogs/DialogManager.cpp"
# from [17c83a36fb60eb7e122c0b80b8e6ead7f8ba5796]
# to [d333fbc6c81e14cb2f1dfc5bbe4ba6d0e78728d1]
#
# patch "src/view/dialogs/DialogManager.h"
# from [eb6eec5ffed8e531e644cfa7da0c13f564339532]
# to [0afd1af8cca28d7519209a560784949e19988e10]
#
# patch "src/view/dialogs/KeyManagement.cpp"
# from [c282dc5376939e8814d89faeb099d5b677e2d07b]
# to [d0e3556aea2c55f38f012973839dfc46973951e1]
#
# patch "src/view/dialogs/KeyManagement.h"
# from [2661c45144f24e9241f4c73719c7e2ba9cc17f9b]
# to [b53a2b1f764b2787cb72beaf6694f1904077e8fd]
#
============================================================
--- res/forms/dialogs/change_key_password.ui 241cbef3ad9e2bad992bef55520c828ab8abd9dd
+++ res/forms/dialogs/change_key_password.ui 241cbef3ad9e2bad992bef55520c828ab8abd9dd
@@ -0,0 +1,170 @@
+
+
+ ChangeKeyPassword
+
+
+ Qt::WindowModal
+
+
+ true
+
+
+
+ 0
+ 0
+ 370
+ 174
+
+
+
+
+ 0
+ 0
+
+
+
+ Change key password
+
+
+
+ :/icons/guitone.png:/icons/guitone.png
+
+
+ false
+
+
+ false
+
+
+
+ QFormLayout::ExpandingFieldsGrow
+
+
+ 16
+
+ -
+
+
+ Old Password
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Password
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Repeat password
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html><head><meta name="qrichtext" content="1" /><style type="text/css">
+p, li { white-space: pre-wrap; }
+</style></head><body style=" font-family:'Lucida Grande'; font-size:13pt; font-weight:400; font-style:normal;">
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Set this option if you don't want to set up a lua hook which tells monotone the passphrase for key decryption.</p>
+<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">WARNING:</span> Passwords are stored unencrypted in guitone's settings!</p></body></html>
+
+
+ remember password
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ ChangeKeyPassword
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ ChangeKeyPassword
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
============================================================
--- src/view/dialogs/ChangeKeyPassword.cpp 9b1251e7a8547a9ad74274a4b8254bf91bf94943
+++ src/view/dialogs/ChangeKeyPassword.cpp 9b1251e7a8547a9ad74274a4b8254bf91bf94943
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Thomas Keller *
+ * address@hidden *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
+ ***************************************************************************/
+
+#include "ChangeKeyPassword.h"
+#include "MonotoneProcess.h"
+#include "Settings.h"
+
+#include
+
+ChangeKeyPassword::ChangeKeyPassword(QWidget * parent) : Dialog(parent)
+{
+ setupUi(this);
+ Dialog::init();
+}
+
+ChangeKeyPassword::~ChangeKeyPassword() {}
+
+void ChangeKeyPassword::init(const QString & hash)
+{
+ keyHash = hash;
+ oldPasswd->clear();
+ newPasswd->clear();
+ newPasswd2->clear();
+}
+
+void ChangeKeyPassword::accept()
+{
+ if (oldPasswd->text().size() == 0 ||
+ newPasswd->text().size() == 0 ||
+ newPasswd2->text().size() == 0)
+ {
+ QMessageBox::information(
+ this,
+ tr("Missing information"),
+ tr("Please fill out all fields."),
+ QMessageBox::Ok
+ );
+ return;
+ }
+
+ if (newPasswd->text().compare(newPasswd2->text()) != 0)
+ {
+ QMessageBox::information(
+ this,
+ tr("Password mismatch"),
+ tr("The entered passwords did not match."),
+ QMessageBox::Ok
+ );
+ return;
+ }
+
+ QStringList args;
+ args << "passphrase" << keyHash;
+
+ QByteArray input;
+ input.append(oldPasswd->text().toUtf8());
+ input.append('\n');
+ input.append(newPasswd->text().toUtf8());
+ input.append('\n');
+ input.append(newPasswd->text().toUtf8());
+ input.append('\n');
+
+ // FIXME: this is a hack: since monotone (up to 0.46 at least) prompts
+ // four times for the current passphrase, we won't get notified if the
+ // key decryption failed until we virtually pressed enter a fourth time
+ // luckily this doesn't change the behaviour of the successful case
+ input.append('\n');
+
+ MonotoneProcess proc;
+ proc.start(args);
+ proc.write(input);
+ proc.waitForFinished(5000);
+
+ QString output = proc.getBufferedOutput();
+ if (!proc.successful())
+ {
+ if (output.indexOf("failed to decrypt old private RSA key") != -1)
+ {
+ QMessageBox::critical(
+ this,
+ tr("Error changing password"),
+ tr("Wrong old password for key %1 given.").arg(keyHash),
+ QMessageBox::Ok, 0, 0
+ );
+ return;
+ }
+
+ C(QString("error changing key passphrase: %1").arg(output));
+
+ QMessageBox::critical(
+ this,
+ tr("Error changing password"),
+ tr("An unknown error occurred - please check the log for details."),
+ QMessageBox::Ok, 0, 0
+ );
+ return;
+ }
+
+ if (rememberPassword->isChecked())
+ {
+ Settings::addItemToMap(
+ "KeyPasswords",
+ keyHash,
+ newPasswd->text()
+ );
+
+ QMessageBox::information(
+ this,
+ tr("Password saved"),
+ tr("Your key password has been saved. Please note that you "
+ "need to re-open the database or workspace you want to "
+ "use this key with."),
+ QMessageBox::Ok
+ );
+ }
+
+ emit passwordChanged();
+ done(QDialog::Accepted);
+}
+
============================================================
--- src/view/dialogs/ChangeKeyPassword.h 2a6c49b172801183406df48c4caee9fc0ee268af
+++ src/view/dialogs/ChangeKeyPassword.h 2a6c49b172801183406df48c4caee9fc0ee268af
@@ -0,0 +1,46 @@
+/***************************************************************************
+ * Copyright (C) 2010 by Thomas Keller *
+ * address@hidden *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program. If not, see . *
+ ***************************************************************************/
+
+#ifndef CHANGE_KEY_PASSWORD_H
+#define CHANGE_KEY_PASSWORD_H
+
+#include "Dialog.h"
+#include "vocab.h"
+#include "ui_change_key_password.h"
+
+class ChangeKeyPassword : public Dialog, private Ui::ChangeKeyPassword
+{
+ Q_OBJECT
+public:
+ ChangeKeyPassword(QWidget *);
+ ~ChangeKeyPassword();
+
+ void init(const QString &);
+
+signals:
+ void passwordChanged();
+
+public slots:
+ void accept();
+
+private:
+ QString keyHash;
+};
+
+#endif
+
============================================================
--- NEWS 7b8445f0080d5a63d84d86cdaa5df474ac6bc126
+++ NEWS c9184fa1e0316e8b89728cf6824c69557d9e37c2
@@ -2,8 +2,14 @@
- NOTE: You need monotone 0.46 or later for this version
- new: create new monotone databases
- new: synchronize with other monotone databases via netsync
+ - new: update workspaces to the selected revision; warn if the new revision
+ is part of another source tree
+ - new: change the passphrase of a key
+ - new: sort and filter the key list
+ - new: remember the entered passphrase of a key for later usage, f.e.
+ in commits or for netsync actions
- new: setup a new project with a given database
- - new: directly select the key to sign a revision with in the commit dialog
+ - new: directly select the key to sign a revision within the commit dialog
- new: link to monotone manual from the help menu (FS#23)
- improved: lighter, more eye-friendly colors for diff views (FS#24)
- bugfix: guitone no longer considers the workspace to be invalid if the last
============================================================
--- guitone.pro 427722d346990785a3b3598c7bc49d40f606c179
+++ guitone.pro 8819a394eeff1b31d1077696920bf2397365d130
@@ -53,6 +53,7 @@ HEADERS = src/view/widgets/TreeView.h \
src/view/dialogs/RevisionDiff.h \
src/view/dialogs/KeyManagement.h \
src/view/dialogs/GenerateKeypair.h \
+ src/view/dialogs/ChangeKeyPassword.h \
src/view/dialogs/About.h \
src/view/dialogs/ChangesetBrowser.h \
src/view/dialogs/RevisionManifest.h \
@@ -143,6 +144,7 @@ SOURCES += src/view/widgets/TreeView.cpp
src/view/dialogs/RevisionDiff.cpp \
src/view/dialogs/KeyManagement.cpp \
src/view/dialogs/GenerateKeypair.cpp \
+ src/view/dialogs/ChangeKeyPassword.cpp \
src/view/dialogs/About.cpp \
src/view/dialogs/ChangesetBrowser.cpp \
src/view/dialogs/RevisionManifest.cpp \
@@ -212,6 +214,7 @@ FORMS += res/forms/dialogs/select_revi
res/forms/dialogs/revision_diff.ui \
res/forms/dialogs/key_management.ui \
res/forms/dialogs/generate_keypair.ui \
+ res/forms/dialogs/change_key_password.ui \
res/forms/dialogs/about.ui \
res/forms/dialogs/changeset_browser.ui \
res/forms/dialogs/manifest.ui \
============================================================
--- src/view/dialogs/DatabaseDialogManager.cpp 114836269d5a2ee7c9d086efdda82d69728f79b6
+++ src/view/dialogs/DatabaseDialogManager.cpp 2cc6cb87b8c1d5661f183fa98e2e9b251c63229c
@@ -176,6 +176,16 @@ void DatabaseDialogManager::showKeyManag
keyManagement, SIGNAL(generateKeypair()),
this, SLOT(showGenerateKeypair())
);
+
+ connect(
+ keyManagement, SIGNAL(changeKeyPassword(const QString &)),
+ this, SLOT(showChangeKeyPassword(const QString &))
+ );
+
+ connect(
+ changeKeyPassword, SIGNAL(passwordChanged()),
+ keyManagement, SLOT(readKeys())
+ );
}
keyManagement->readKeys();
============================================================
--- src/view/dialogs/DialogManager.cpp 17c83a36fb60eb7e122c0b80b8e6ead7f8ba5796
+++ src/view/dialogs/DialogManager.cpp d333fbc6c81e14cb2f1dfc5bbe4ba6d0e78728d1
@@ -20,14 +20,16 @@ DialogManager::DialogManager(QWidget * p
#include "vocab.h"
DialogManager::DialogManager(QWidget * parentWidget)
- : QObject(parentWidget), about(0), preferences(0), createDatabase(0)
+ : QObject(parentWidget), about(0), preferences(0),
+ createDatabase(0), changeKeyPassword(0)
{}
DialogManager::~DialogManager()
{
- if (about) delete about;
- if (preferences) delete preferences;
- if (createDatabase) delete createDatabase;
+ if (about) delete about;
+ if (preferences) delete preferences;
+ if (createDatabase) delete createDatabase;
+ if (changeKeyPassword) delete changeKeyPassword;
}
QWidget * DialogManager::parentWidget() const
@@ -75,6 +77,22 @@ void DialogManager::showCreateDatabase()
showDialog(createDatabase);
}
+void DialogManager::showChangeKeyPassword(const QString & keyHash)
+{
+ if (!changeKeyPassword)
+ {
+ changeKeyPassword = new ChangeKeyPassword(parentWidget());
+
+ connect(
+ changeKeyPassword, SIGNAL(passwordChanged()),
+ this, SIGNAL(passwordChanged())
+ );
+ }
+
+ changeKeyPassword->init(keyHash);
+ showDialog(changeKeyPassword);
+}
+
void DialogManager::showDialog(Dialog * dlg)
{
if (!openDialogs.contains(dlg))
============================================================
--- src/view/dialogs/DialogManager.h eb6eec5ffed8e531e644cfa7da0c13f564339532
+++ src/view/dialogs/DialogManager.h 0afd1af8cca28d7519209a560784949e19988e10
@@ -22,6 +22,7 @@
#include "About.h"
#include "Preferences.h"
#include "CreateDatabase.h"
+#include "ChangeKeyPassword.h"
#include "vocab.h"
#include
@@ -39,18 +40,21 @@ public slots:
void showAbout();
void showPreferences();
void showCreateDatabase();
+ void showChangeKeyPassword(const QString &);
signals:
void databaseCreated(const QString &);
+ void passwordChanged();
void allDialogsClosed();
protected:
QWidget * parentWidget() const;
void showDialog(Dialog *);
- About * about;
- Preferences * preferences;
- CreateDatabase * createDatabase;
+ About * about;
+ Preferences * preferences;
+ CreateDatabase * createDatabase;
+ ChangeKeyPassword * changeKeyPassword;
private:
void cleanup();
============================================================
--- src/view/dialogs/KeyManagement.cpp c282dc5376939e8814d89faeb099d5b677e2d07b
+++ src/view/dialogs/KeyManagement.cpp d0e3556aea2c55f38f012973839dfc46973951e1
@@ -55,39 +55,61 @@ KeyManagement::KeyManagement(QWidget * p
proxyModel, SLOT(setFilterWildcard(const QString &))
);
- popupMenu = new QMenu(this);
+ actCopyHash = new QAction(tr("Copy key hash to clipboard"), this);
+ connect(
+ actCopyHash, SIGNAL(triggered()),
+ this, SLOT(copyKeyHashToClipboard())
+ );
- QAction * act = new QAction(tr("Copy key hash to clipboard"), this);
- connect(act, SIGNAL(triggered()), this, SLOT(copyKeyHashToClipboard()));
- popupMenu->addAction(act);
+ actCopyGivenName = new QAction(tr("Copy given name to clipboard"), this);
+ connect(
+ actCopyGivenName, SIGNAL(triggered()),
+ this, SLOT(copyGivenNameToClipboard())
+ );
- act = new QAction(tr("Copy given name to clipboard"), this);
- connect(act, SIGNAL(triggered()), this, SLOT(copyGivenNameToClipboard()));
- popupMenu->addAction(act);
+ actCopyLocalName = new QAction(tr("Copy local name to clipboard"), this);
+ connect(
+ actCopyLocalName, SIGNAL(triggered()),
+ this, SLOT(copyLocalNameToClipboard())
+ );
- act = new QAction(tr("Copy local name to clipboard"), this);
- connect(act, SIGNAL(triggered()), this, SLOT(copyLocalNameToClipboard()));
- popupMenu->addAction(act);
+ actCopyPublicKey = new QAction(tr("Copy public key data to clipboard"), this);
+ connect(
+ actCopyPublicKey, SIGNAL(triggered()),
+ this, SLOT(copyPubkeyDataToClipboard())
+ );
- popupMenu->addSeparator();
+ actForgetPassword = new QAction(tr("Forget remembered password"), this);
+ connect(
+ actForgetPassword, SIGNAL(triggered()),
+ this, SLOT(forgetPassword())
+ );
- act = new QAction(tr("Copy public key data to clipboard"), this);
- connect(act, SIGNAL(triggered()), this, SLOT(copyPubkeyDataToClipboard()));
- popupMenu->addAction(act);
+ actChangePassword = new QAction(tr("Change password"), this);
+ connect(
+ actChangePassword, SIGNAL(triggered()),
+ this, SLOT(changePassword())
+ );
- popupMenu->addSeparator();
-
- act = new QAction(tr("Drop key"), this);
- connect(act, SIGNAL(triggered()), this, SLOT(dropKey()));
- popupMenu->addAction(act);
+ actDrop = new QAction(tr("Drop key"), this);
+ connect(
+ actDrop, SIGNAL(triggered()),
+ this, SLOT(dropKey())
+ );
}
KeyManagement::~KeyManagement()
{
delete proxyModel;
delete model;
- qDeleteAll(popupMenu->findChildren());
- delete popupMenu;
+
+ delete actCopyHash;
+ delete actCopyGivenName;
+ delete actCopyLocalName;
+ delete actCopyPublicKey;
+ delete actForgetPassword;
+ delete actChangePassword;
+ delete actDrop;
}
void KeyManagement::readKeys()
@@ -98,7 +120,33 @@ void KeyManagement::contextMenuEvent(con
void KeyManagement::contextMenuEvent(const QModelIndexList & indexList, const QPoint & p)
{
Q_UNUSED(indexList);
- popupMenu->exec(p);
+
+ Key * key = getKeyFromSelection();
+ if (key == 0) return;
+
+ QMenu popupMenu;
+
+ popupMenu.addAction(actCopyHash);
+ popupMenu.addAction(actCopyGivenName);
+ popupMenu.addAction(actCopyLocalName);
+
+ popupMenu.addSeparator();
+ popupMenu.addAction(actCopyPublicKey);
+
+ if (key->isPrivate())
+ {
+ popupMenu.addSeparator();
+ popupMenu.addAction(actChangePassword);
+ if (!Settings::getItemFromMap("KeyPasswords", key->hash).isNull())
+ {
+ popupMenu.addAction(actForgetPassword);
+ }
+ }
+
+ popupMenu.addSeparator();
+ popupMenu.addAction(actDrop);
+
+ popupMenu.exec(p);
}
Key * KeyManagement::getKeyFromSelection() const
@@ -116,8 +164,7 @@ void KeyManagement::copyKeyHashToClipboa
void KeyManagement::copyKeyHashToClipboard()
{
Key * key = getKeyFromSelection();
- if (key == 0)
- return;
+ if (key == 0) return;
QClipboard * clipboard = QApplication::clipboard();
clipboard->setText(key->hash);
@@ -126,8 +173,7 @@ void KeyManagement::copyGivenNameToClipb
void KeyManagement::copyGivenNameToClipboard()
{
Key * key = getKeyFromSelection();
- if (key == 0)
- return;
+ if (key == 0) return;
QClipboard * clipboard = QApplication::clipboard();
clipboard->setText(key->given_name);
@@ -136,8 +182,7 @@ void KeyManagement::copyLocalNameToClipb
void KeyManagement::copyLocalNameToClipboard()
{
Key * key = getKeyFromSelection();
- if (key == 0)
- return;
+ if (key == 0) return;
QClipboard * clipboard = QApplication::clipboard();
clipboard->setText(key->local_name);
@@ -147,8 +192,7 @@ void KeyManagement::copyPubkeyDataToClip
void KeyManagement::copyPubkeyDataToClipboard()
{
Key * key = getKeyFromSelection();
- if (key == 0)
- return;
+ if (key == 0) return;
QClipboard * clipboard = QApplication::clipboard();
@@ -171,12 +215,27 @@ void KeyManagement::copyPubkeyDataToClip
clipboard->setText(output);
}
-// TODO: should be converted to automate dropkey, if available
+void KeyManagement::forgetPassword()
+{
+ Key * key = getKeyFromSelection();
+ if (key == 0) return;
+
+ Settings::removeItemFromMap("KeyPasswords", key->hash);
+ model->readKeys();
+}
+
+void KeyManagement::changePassword()
+{
+ Key * key = getKeyFromSelection();
+ if (key == 0) return;
+ emit changeKeyPassword(key->hash);
+}
+
+
void KeyManagement::dropKey()
{
Key * key = getKeyFromSelection();
- if (key == 0)
- return;
+ if (key == 0) return;
QMessageBox::StandardButton btn = QMessageBox::question(
this,
============================================================
--- src/view/dialogs/KeyManagement.h 2661c45144f24e9241f4c73719c7e2ba9cc17f9b
+++ src/view/dialogs/KeyManagement.h b53a2b1f764b2787cb72beaf6694f1904077e8fd
@@ -38,6 +38,7 @@ signals:
void readKeys();
signals:
+ void changeKeyPassword(const QString &);
void generateKeypair();
private:
@@ -45,15 +46,24 @@ private:
Keys * model;
QSortFilterProxyModel * proxyModel;
- QMenu * popupMenu;
DatabaseFile databaseFile;
+ QAction * actCopyHash;
+ QAction * actCopyGivenName;
+ QAction * actCopyLocalName;
+ QAction * actCopyPublicKey;
+ QAction * actForgetPassword;
+ QAction * actChangePassword;
+ QAction * actDrop;
+
private slots:
void contextMenuEvent(const QModelIndexList &, const QPoint &);
void copyKeyHashToClipboard();
void copyGivenNameToClipboard();
void copyLocalNameToClipboard();
void copyPubkeyDataToClipboard();
+ void forgetPassword();
+ void changePassword();
void dropKey();
};