Expand GUI to allow changing the master key.

This commit is contained in:
Felix Geyer 2012-01-13 17:52:37 +01:00
parent 0ad1bf0a70
commit 2612fc8e44
10 changed files with 345 additions and 4 deletions

View File

@ -46,6 +46,7 @@ set(keepassx_SOURCES
format/KeePass2Writer.cpp format/KeePass2Writer.cpp
format/KeePass2XmlReader.cpp format/KeePass2XmlReader.cpp
format/KeePass2XmlWriter.cpp format/KeePass2XmlWriter.cpp
gui/ChangeMasterKeyWidget.cpp
gui/DatabaseTabWidget.cpp gui/DatabaseTabWidget.cpp
gui/DatabaseWidget.cpp gui/DatabaseWidget.cpp
gui/EditEntryWidget.cpp gui/EditEntryWidget.cpp
@ -72,6 +73,7 @@ set(keepassx_MOC
core/Entry.h core/Entry.h
core/Group.h core/Group.h
core/Metadata.h core/Metadata.h
gui/ChangeMasterKeyWidget.h
gui/DatabaseTabWidget.h gui/DatabaseTabWidget.h
gui/DatabaseWidget.h gui/DatabaseWidget.h
gui/EditEntryWidget.h gui/EditEntryWidget.h
@ -89,6 +91,7 @@ set(keepassx_MOC
) )
set(keepassx_FORMS set(keepassx_FORMS
gui/ChangeMasterKeyWidget.ui
gui/EditEntryWidget.ui gui/EditEntryWidget.ui
gui/EditEntryWidgetMain.ui gui/EditEntryWidgetMain.ui
gui/EditEntryWidgetNotes.ui gui/EditEntryWidgetNotes.ui

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* 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 2 or (at your option)
* version 3 of the License.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "ChangeMasterKeyWidget.h"
#include "ui_ChangeMasterKeyWidget.h"
#include "keys/FileKey.h"
#include "keys/PasswordKey.h"
ChangeMasterKeyWidget::ChangeMasterKeyWidget(QWidget* parent)
: QWidget(parent)
, m_ui(new Ui::ChangeMasterKeyWidget())
{
m_ui->setupUi(this);
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(generateKey()));
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
}
ChangeMasterKeyWidget::~ChangeMasterKeyWidget()
{
}
void ChangeMasterKeyWidget::clearForms()
{
m_key.clear();
m_ui->passwordGroup->setChecked(true);
m_ui->enterPasswordEdit->setText("");
m_ui->repeatPasswordEdit->setText("");
m_ui->keyFileGroup->setChecked(false);
// TODO clear m_ui->keyFileCombo
}
CompositeKey ChangeMasterKeyWidget::newMasterKey()
{
return m_key;
}
QLabel* ChangeMasterKeyWidget::headlineLabel()
{
return m_ui->headlineLabel;
}
void ChangeMasterKeyWidget::generateKey()
{
m_key.clear();
if (m_ui->passwordGroup->isChecked()) {
m_key.addKey(PasswordKey(m_ui->enterPasswordEdit->text()));
}
if (m_ui->keyFileGroup->isChecked()) {
FileKey fileKey;
QString errorMsg;
if (!fileKey.load(m_ui->keyFileCombo->currentText()), &errorMsg) {
// TODO error handling
}
m_key.addKey(fileKey);
}
Q_EMIT editFinished(true);
}
void ChangeMasterKeyWidget::reject()
{
Q_EMIT editFinished(false);
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
*
* 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 2 or (at your option)
* version 3 of the License.
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef KEEPASSX_CHANGEMASTERKEYWIDGET_H
#define KEEPASSX_CHANGEMASTERKEYWIDGET_H
#include <QtCore/QScopedPointer>
#include <QtGui/QWidget>
#include "keys/CompositeKey.h"
class QLabel;
namespace Ui {
class ChangeMasterKeyWidget;
}
class ChangeMasterKeyWidget : public QWidget
{
Q_OBJECT
public:
explicit ChangeMasterKeyWidget(QWidget* parent = 0);
~ChangeMasterKeyWidget();
void clearForms();
CompositeKey newMasterKey();
QLabel* headlineLabel();
Q_SIGNALS:
void editFinished(bool accepted);
private Q_SLOTS:
void generateKey();
void reject();
private:
QScopedPointer<Ui::ChangeMasterKeyWidget> m_ui;
CompositeKey m_key;
Q_DISABLE_COPY(ChangeMasterKeyWidget)
};
#endif // KEEPASSX_CHANGEMASTERKEYWIDGET_H

View File

@ -0,0 +1,150 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ChangeMasterKeyWidget</class>
<widget class="QWidget" name="ChangeMasterKeyWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>438</width>
<height>237</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="headlineLabel"/>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<height>3</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="passwordGroup">
<property name="title">
<string>Password</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="enterPasswordLabel">
<property name="text">
<string>Enter password:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLineEdit" name="enterPasswordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="togglePasswordButton">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="repeatPasswordLabel">
<property name="text">
<string>Repeat password:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="repeatPasswordEdit">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="keyFileGroup">
<property name="title">
<string>Key file</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<widget class="QPushButton" name="browseKeyFileButton">
<property name="text">
<string>Browse</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="createKeyFileButton">
<property name="text">
<string>Create</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="keyFileCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -223,6 +223,11 @@ void DatabaseTabWidget::saveDatabaseAs(int index)
saveDatabaseAs(indexDatabase(index)); saveDatabaseAs(indexDatabase(index));
} }
void DatabaseTabWidget::changeMasterKey()
{
currentDatabaseWidget()->switchToMasterKeyChange();
}
void DatabaseTabWidget::createEntry() void DatabaseTabWidget::createEntry()
{ {
currentDatabaseWidget()->createEntry(); currentDatabaseWidget()->createEntry();

View File

@ -56,11 +56,15 @@ public Q_SLOTS:
void saveDatabase(int index = -1); void saveDatabase(int index = -1);
void saveDatabaseAs(int index = -1); void saveDatabaseAs(int index = -1);
void closeDatabase(int index = -1); void closeDatabase(int index = -1);
void changeMasterKey();
void createEntry(); void createEntry();
void editEntry(); void editEntry();
void createGroup(); void createGroup();
void editGroup(); void editGroup();
Q_SIGNALS:
void entrySelectionChanged(bool singleEntrySelected);
private Q_SLOTS: private Q_SLOTS:
void updateTabName(Database* db); void updateTabName(Database* db);
void openDatabaseDialog(); void openDatabaseDialog();
@ -68,9 +72,6 @@ private Q_SLOTS:
void openDatabaseCleanup(); void openDatabaseCleanup();
void emitEntrySelectionChanged(); void emitEntrySelectionChanged();
Q_SIGNALS:
void entrySelectionChanged(bool singleEntrySelected);
private: private:
void saveDatabase(Database* db); void saveDatabase(Database* db);
void saveDatabaseAs(Database* db); void saveDatabaseAs(Database* db);

View File

@ -18,8 +18,10 @@
#include "DatabaseWidget.h" #include "DatabaseWidget.h"
#include <QtGui/QHBoxLayout> #include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QSplitter> #include <QtGui/QSplitter>
#include "gui/ChangeMasterKeyWidget.h"
#include "gui/EditEntryWidget.h" #include "gui/EditEntryWidget.h"
#include "gui/EditGroupWidget.h" #include "gui/EditGroupWidget.h"
#include "gui/EntryView.h" #include "gui/EntryView.h"
@ -27,6 +29,7 @@
DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent) DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
: QStackedWidget(parent) : QStackedWidget(parent)
, m_db(db)
, m_newGroup(0) , m_newGroup(0)
, m_newEntry(0) , m_newEntry(0)
, m_newParent(0) , m_newParent(0)
@ -56,15 +59,23 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_editEntryWidget = new EditEntryWidget(); m_editEntryWidget = new EditEntryWidget();
m_editGroupWidget = new EditGroupWidget(); m_editGroupWidget = new EditGroupWidget();
m_changeMasterKeyWidget = new ChangeMasterKeyWidget();
m_changeMasterKeyWidget->headlineLabel()->setText(tr("Change master key"));
QFont headlineLabelFont = m_changeMasterKeyWidget->headlineLabel()->font();
headlineLabelFont.setBold(true);
headlineLabelFont.setPointSize(headlineLabelFont.pointSize() + 2);
m_changeMasterKeyWidget->headlineLabel()->setFont(headlineLabelFont);
addWidget(m_mainWidget); addWidget(m_mainWidget);
addWidget(m_editEntryWidget); addWidget(m_editEntryWidget);
addWidget(m_editGroupWidget); addWidget(m_editGroupWidget);
addWidget(m_changeMasterKeyWidget);
connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*))); connect(m_groupView, SIGNAL(groupChanged(Group*)), m_entryView, SLOT(setGroup(Group*)));
connect(m_entryView, SIGNAL(entryActivated(Entry*)), SLOT(switchToEntryEdit(Entry*))); connect(m_entryView, SIGNAL(entryActivated(Entry*)), SLOT(switchToEntryEdit(Entry*)));
connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool))); connect(m_editEntryWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool)));
connect(m_editGroupWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool))); connect(m_editGroupWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool)));
connect(m_changeMasterKeyWidget, SIGNAL(editFinished(bool)), SLOT(updateMasterKey(bool)));
setCurrentIndex(0); setCurrentIndex(0);
} }
@ -139,6 +150,16 @@ void DatabaseWidget::switchToGroupEdit(Group* group, bool create)
m_editGroupWidget->loadGroup(group, create); m_editGroupWidget->loadGroup(group, create);
setCurrentIndex(2); setCurrentIndex(2);
} }
void DatabaseWidget::updateMasterKey(bool accepted)
{
if (accepted) {
m_db->setKey(m_changeMasterKeyWidget->newMasterKey());
}
setCurrentIndex(0);
}
void DatabaseWidget::switchToEntryEdit() void DatabaseWidget::switchToEntryEdit()
{ {
switchToEntryEdit(m_entryView->currentEntry(), false); switchToEntryEdit(m_entryView->currentEntry(), false);
@ -148,3 +169,9 @@ void DatabaseWidget::switchToGroupEdit()
{ {
switchToGroupEdit(m_groupView->currentGroup(), false); switchToGroupEdit(m_groupView->currentGroup(), false);
} }
void DatabaseWidget::switchToMasterKeyChange()
{
m_changeMasterKeyWidget->clearForms();
setCurrentIndex(3);
}

View File

@ -20,6 +20,7 @@
#include <QtGui/QStackedWidget> #include <QtGui/QStackedWidget>
class ChangeMasterKeyWidget;
class Database; class Database;
class EditEntryWidget; class EditEntryWidget;
class EditGroupWidget; class EditGroupWidget;
@ -42,17 +43,21 @@ public Q_SLOTS:
void createGroup(); void createGroup();
void switchToEntryEdit(); void switchToEntryEdit();
void switchToGroupEdit(); void switchToGroupEdit();
void switchToMasterKeyChange();
private Q_SLOTS: private Q_SLOTS:
void switchToView(bool accepted); void switchToView(bool accepted);
void switchToEntryEdit(Entry* entry); void switchToEntryEdit(Entry* entry);
void switchToEntryEdit(Entry* entry, bool create); void switchToEntryEdit(Entry* entry, bool create);
void switchToGroupEdit(Group* entry, bool create); void switchToGroupEdit(Group* entry, bool create);
void updateMasterKey(bool accepted);
private: private:
Database* m_db;
QWidget* m_mainWidget; QWidget* m_mainWidget;
EditEntryWidget* m_editEntryWidget; EditEntryWidget* m_editEntryWidget;
EditGroupWidget* m_editGroupWidget; EditGroupWidget* m_editGroupWidget;
ChangeMasterKeyWidget* m_changeMasterKeyWidget;
GroupView* m_groupView; GroupView* m_groupView;
EntryView* m_entryView; EntryView* m_entryView;
Group* m_newGroup; Group* m_newGroup;

View File

@ -39,6 +39,7 @@ MainWindow::MainWindow()
connect(m_ui->actionDatabaseSave, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabase())); connect(m_ui->actionDatabaseSave, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabase()));
connect(m_ui->actionDatabaseSaveAs, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseAs())); connect(m_ui->actionDatabaseSaveAs, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseAs()));
connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeDatabase())); connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeDatabase()));
connect(m_ui->actionChangeMasterKey, SIGNAL(triggered()), m_ui->tabWidget, SLOT(changeMasterKey()));
connect(m_ui->actionEntryNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createEntry())); connect(m_ui->actionEntryNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createEntry()));
connect(m_ui->actionEntryEdit, SIGNAL(triggered()), m_ui->tabWidget, SLOT(editEntry())); connect(m_ui->actionEntryEdit, SIGNAL(triggered()), m_ui->tabWidget, SLOT(editEntry()));
connect(m_ui->actionGroupNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createGroup())); connect(m_ui->actionGroupNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createGroup()));
@ -60,4 +61,5 @@ void MainWindow::currentTabChanged(int index)
m_ui->actionEntryNew->setEnabled(hasTab); m_ui->actionEntryNew->setEnabled(hasTab);
m_ui->actionGroupNew->setEnabled(hasTab); m_ui->actionGroupNew->setEnabled(hasTab);
m_ui->actionGroupEdit->setEnabled(hasTab); m_ui->actionGroupEdit->setEnabled(hasTab);
m_ui->actionChangeMasterKey->setEnabled(hasTab);
} }

View File

@ -36,7 +36,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>800</width> <width>800</width>
<height>20</height> <height>19</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -49,6 +49,8 @@
<addaction name="actionDatabaseSaveAs"/> <addaction name="actionDatabaseSaveAs"/>
<addaction name="actionDatabaseClose"/> <addaction name="actionDatabaseClose"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionChangeMasterKey"/>
<addaction name="separator"/>
<addaction name="actionQuit"/> <addaction name="actionQuit"/>
</widget> </widget>
<widget class="QMenu" name="menuHelp"> <widget class="QMenu" name="menuHelp">
@ -187,6 +189,14 @@
<string>Save database as</string> <string>Save database as</string>
</property> </property>
</action> </action>
<action name="actionChangeMasterKey">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Change master key</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>