Implement database locking.

Closes #35
This commit is contained in:
Felix Geyer 2012-10-12 12:12:00 +02:00
parent 8117809901
commit e166722026
15 changed files with 297 additions and 54 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

View File

@ -82,6 +82,7 @@ set(keepassx_SOURCES
gui/MainWindow.cpp
gui/SettingsWidget.cpp
gui/SortFilterHideProxyModel.cpp
gui/UnlockDatabaseWidget.cpp
gui/WelcomeWidget.cpp
gui/entry/AutoTypeAssociationsModel.cpp
gui/entry/EditEntryWidget.cpp
@ -137,6 +138,7 @@ set(keepassx_MOC
gui/MainWindow.h
gui/SettingsWidget.h
gui/SortFilterHideProxyModel.h
gui/UnlockDatabaseWidget.h
gui/WelcomeWidget.h
gui/entry/AutoTypeAssociationsModel.h
gui/entry/EditEntryWidget.h

View File

@ -94,31 +94,11 @@ void DatabaseOpenWidget::enterKey(const QString& pw, const QString& keyFile)
void DatabaseOpenWidget::openDatabase()
{
KeePass2Reader reader;
CompositeKey masterKey;
if (m_ui->checkPassword->isChecked()) {
masterKey.addKey(PasswordKey(m_ui->editPassword->text()));
CompositeKey masterKey = databaseKey();
if (masterKey.isEmpty()) {
return;
}
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
if (m_ui->checkKeyFile->isChecked()) {
FileKey key;
QString keyFilename = m_ui->comboKeyFile->currentText();
QString errorMsg;
if (!key.load(keyFilename, &errorMsg)) {
QMessageBox::warning(this, tr("Error"), tr("Can't open key file:\n%1").arg(errorMsg));
return;
}
masterKey.addKey(key);
lastKeyFiles[m_filename] = keyFilename;
}
else {
lastKeyFiles.remove(m_filename);
}
config()->set("LastKeyFiles", lastKeyFiles);
QFile file(m_filename);
if (!file.open(QIODevice::ReadOnly)) {
// TODO: error message
@ -141,6 +121,36 @@ void DatabaseOpenWidget::openDatabase()
}
}
CompositeKey DatabaseOpenWidget::databaseKey()
{
CompositeKey masterKey;
if (m_ui->checkPassword->isChecked()) {
masterKey.addKey(PasswordKey(m_ui->editPassword->text()));
}
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
if (m_ui->checkKeyFile->isChecked()) {
FileKey key;
QString keyFilename = m_ui->comboKeyFile->currentText();
QString errorMsg;
if (!key.load(keyFilename, &errorMsg)) {
QMessageBox::warning(this, tr("Error"), tr("Can't open key file:\n%1").arg(errorMsg));
return CompositeKey();
}
masterKey.addKey(key);
lastKeyFiles[m_filename] = keyFilename;
}
else {
lastKeyFiles.remove(m_filename);
}
config()->set("LastKeyFiles", lastKeyFiles);
return masterKey;
}
void DatabaseOpenWidget::reject()
{
Q_EMIT editFinished(false);

View File

@ -21,6 +21,7 @@
#include <QtCore/QScopedPointer>
#include "gui/DialogyWidget.h"
#include "keys/CompositeKey.h"
class Database;
class QFile;
@ -43,6 +44,9 @@ public:
Q_SIGNALS:
void editFinished(bool accepted);
protected:
CompositeKey databaseKey();
protected Q_SLOTS:
virtual void openDatabase();
void reject();

View File

@ -297,6 +297,7 @@ void DatabaseTabWidget::saveDatabaseAs(Database* db)
dbStruct.filePath = fileInfo.absoluteFilePath();
dbStruct.canonicalFilePath = fileInfo.canonicalFilePath();
dbStruct.fileName = fileInfo.fileName();
dbStruct.dbWidget->updateFilename(dbStruct.filePath);
updateTabName(db);
updateLastDatabases(dbStruct.filePath);
}
@ -391,20 +392,35 @@ void DatabaseTabWidget::updateTabName(Database* db)
tabName = QString("%1 [%2]").arg(db->metadata()->name(), tr("New database"));
}
}
if (dbStruct.dbWidget->currentMode() == DatabaseWidget::LockedMode) {
tabName.append(QString(" [%1]").arg(tr("locked")));
}
if (dbStruct.modified) {
tabName.append("*");
}
setTabText(index, tabName);
Q_EMIT tabNameChanged();
}
void DatabaseTabWidget::updateTabNameFromSender()
void DatabaseTabWidget::updateTabNameFromDbSender()
{
Q_ASSERT(qobject_cast<Database*>(sender()));
updateTabName(static_cast<Database*>(sender()));
}
void DatabaseTabWidget::updateTabNameFromDbWidgetSender()
{
Q_ASSERT(qobject_cast<DatabaseWidget*>(sender()));
Q_ASSERT(databaseFromDatabaseWidget(qobject_cast<DatabaseWidget*>(sender())));
DatabaseWidget* dbWidget = static_cast<DatabaseWidget*>(sender());
updateTabName(databaseFromDatabaseWidget(dbWidget));
}
int DatabaseTabWidget::databaseIndex(Database* db)
{
QWidget* dbWidget = m_dbList.value(db).dbWidget;
@ -466,6 +482,7 @@ void DatabaseTabWidget::insertDatabase(Database* db, const DatabaseManagerStruct
connectDatabase(db);
connect(dbStruct.dbWidget, SIGNAL(closeRequest()), SLOT(closeDatabaseFromSender()));
connect(dbStruct.dbWidget, SIGNAL(databaseChanged(Database*)), SLOT(changeDatabase(Database*)));
connect(dbStruct.dbWidget, SIGNAL(unlockedDatabase()), SLOT(updateTabNameFromDbWidgetSender()));
}
DatabaseWidget* DatabaseTabWidget::currentDatabaseWidget()
@ -479,6 +496,37 @@ DatabaseWidget* DatabaseTabWidget::currentDatabaseWidget()
}
}
bool DatabaseTabWidget::hasLockableDatabases()
{
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
while (i.hasNext()) {
i.next();
DatabaseWidget::Mode mode = i.value().dbWidget->currentMode();
if ((mode == DatabaseWidget::ViewMode || mode == DatabaseWidget::EditMode)
&& i.value().dbWidget->dbHasKey()) {
return true;
}
}
return false;
}
void DatabaseTabWidget::lockDatabases()
{
QHashIterator<Database*, DatabaseManagerStruct> i(m_dbList);
while (i.hasNext()) {
i.next();
DatabaseWidget::Mode mode = i.value().dbWidget->currentMode();
if ((mode == DatabaseWidget::ViewMode || mode == DatabaseWidget::EditMode)
&& i.value().dbWidget->dbHasKey()) {
i.value().dbWidget->lock();
updateTabName(i.key());
}
}
}
void DatabaseTabWidget::modified()
{
Q_ASSERT(qobject_cast<Database*>(sender()));
@ -535,7 +583,7 @@ void DatabaseTabWidget::connectDatabase(Database* newDb, Database* oldDb)
oldDb->disconnect(this);
}
connect(newDb, SIGNAL(nameTextChanged()), SLOT(updateTabNameFromSender()));
connect(newDb, SIGNAL(nameTextChanged()), SLOT(updateTabNameFromDbSender()));
connect(newDb, SIGNAL(modified()), SLOT(modified()));
newDb->setEmitModified(true);
}

View File

@ -53,6 +53,7 @@ public:
void openDatabase(const QString& fileName, const QString& pw = QString(),
const QString& keyFile = QString());
DatabaseWidget* currentDatabaseWidget();
bool hasLockableDatabases();
static const int LastDatabasesCount;
@ -69,13 +70,15 @@ public Q_SLOTS:
void changeDatabaseSettings();
bool readOnly(int index = -1);
void performGlobalAutoType();
void lockDatabases();
Q_SIGNALS:
void tabNameChanged();
private Q_SLOTS:
void updateTabName(Database* db);
void updateTabNameFromSender();
void updateTabNameFromDbSender();
void updateTabNameFromDbWidgetSender();
void modified();
void toggleTabbar();
void changeDatabase(Database* newDb);

View File

@ -36,6 +36,7 @@
#include "gui/DatabaseOpenWidget.h"
#include "gui/DatabaseSettingsWidget.h"
#include "gui/KeePass1OpenWidget.h"
#include "gui/UnlockDatabaseWidget.h"
#include "gui/entry/EditEntryWidget.h"
#include "gui/entry/EntryView.h"
#include "gui/group/EditGroupWidget.h"
@ -121,6 +122,8 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
m_databaseOpenWidget->setObjectName("databaseOpenWidget");
m_keepass1OpenWidget = new KeePass1OpenWidget();
m_keepass1OpenWidget->setObjectName("keepass1OpenWidget");
m_unlockDatabaseWidget = new UnlockDatabaseWidget();
m_unlockDatabaseWidget->setObjectName("unlockDatabaseWidget");
addWidget(m_mainWidget);
addWidget(m_editEntryWidget);
addWidget(m_editGroupWidget);
@ -129,6 +132,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
addWidget(m_historyEditEntryWidget);
addWidget(m_databaseOpenWidget);
addWidget(m_keepass1OpenWidget);
addWidget(m_unlockDatabaseWidget);
connect(m_groupView, SIGNAL(groupChanged(Group*)), this, SLOT(clearLastGroup(Group*)));
connect(m_groupView, SIGNAL(groupChanged(Group*)), SIGNAL(groupChanged()));
@ -143,6 +147,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_databaseSettingsWidget, SIGNAL(editFinished(bool)), SLOT(switchToView(bool)));
connect(m_databaseOpenWidget, SIGNAL(editFinished(bool)), SLOT(openDatabase(bool)));
connect(m_keepass1OpenWidget, SIGNAL(editFinished(bool)), SLOT(openDatabase(bool)));
connect(m_unlockDatabaseWidget, SIGNAL(editFinished(bool)), SLOT(unlockDatabase(bool)));
connect(this, SIGNAL(currentChanged(int)), this, SLOT(emitCurrentModeChanged()));
connect(m_searchUi->searchEdit, SIGNAL(textChanged(QString)), this, SLOT(startSearchTimer()));
connect(m_searchUi->caseSensitiveCheckBox, SIGNAL(toggled(bool)), this, SLOT(startSearch()));
@ -151,7 +156,7 @@ DatabaseWidget::DatabaseWidget(Database* db, QWidget* parent)
connect(m_searchTimer, SIGNAL(timeout()), this, SLOT(search()));
connect(closeAction, SIGNAL(triggered()), this, SLOT(closeSearch()));
setCurrentIndex(0);
setCurrentWidget(m_mainWidget);
}
DatabaseWidget::~DatabaseWidget()
@ -160,22 +165,17 @@ DatabaseWidget::~DatabaseWidget()
DatabaseWidget::Mode DatabaseWidget::currentMode()
{
switch (currentIndex()) {
case -1:
if (currentWidget() == Q_NULLPTR) {
return DatabaseWidget::None;
case 0:
}
else if (currentWidget() == m_mainWidget) {
return DatabaseWidget::ViewMode;
case 1: // entry edit
case 2: // group edit
case 3: // change master key
case 4: // database settings
case 5: // entry history
case 6: // open database
case 7: // keepass 1 import
}
else if (currentWidget() == m_unlockDatabaseWidget) {
return DatabaseWidget::LockedMode;
}
else {
return DatabaseWidget::EditMode;
default:
Q_ASSERT(false);
return DatabaseWidget::None;
}
}
@ -347,12 +347,20 @@ int DatabaseWidget::addWidget(QWidget* w)
}
void DatabaseWidget::setCurrentIndex(int index)
{
// use setCurrentWidget() instead
// index is not reliable
Q_UNUSED(index);
Q_ASSERT(false);
}
void DatabaseWidget::setCurrentWidget(QWidget* widget)
{
if (currentWidget()) {
currentWidget()->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
}
QStackedWidget::setCurrentIndex(index);
QStackedWidget::setCurrentWidget(widget);
if (currentWidget()) {
currentWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
@ -390,18 +398,18 @@ void DatabaseWidget::switchToView(bool accepted)
m_newParent = Q_NULLPTR;
}
setCurrentIndex(0);
setCurrentWidget(m_mainWidget);
}
void DatabaseWidget::switchToHistoryView(Entry* entry)
{
m_historyEditEntryWidget->loadEntry(entry, false, true, "", m_db);
setCurrentIndex(5);
setCurrentWidget(m_historyEditEntryWidget);
}
void DatabaseWidget::switchBackToEntryEdit()
{
setCurrentIndex(1);
setCurrentWidget(m_editEntryWidget);
}
void DatabaseWidget::switchToEntryEdit(Entry* entry)
@ -419,13 +427,13 @@ void DatabaseWidget::switchToEntryEdit(Entry* entry, bool create)
Q_ASSERT(group);
m_editEntryWidget->loadEntry(entry, create, false, group->name(), m_db);
setCurrentIndex(1);
setCurrentWidget(m_editEntryWidget);
}
void DatabaseWidget::switchToGroupEdit(Group* group, bool create)
{
m_editGroupWidget->loadGroup(group, create, m_db);
setCurrentIndex(2);
setCurrentWidget(m_editGroupWidget);
}
void DatabaseWidget::updateMasterKey(bool accepted)
@ -440,7 +448,7 @@ void DatabaseWidget::updateMasterKey(bool accepted)
return;
}
setCurrentIndex(0);
setCurrentWidget(m_mainWidget);
}
void DatabaseWidget::openDatabase(bool accepted)
@ -451,7 +459,7 @@ void DatabaseWidget::openDatabase(bool accepted)
m_groupView->changeDatabase(m_db);
Q_EMIT databaseChanged(m_db);
delete oldDb;
setCurrentIndex(0);
setCurrentWidget(m_mainWidget);
// We won't need those anymore and KeePass1OpenWidget closes
// the file in its dtor.
@ -468,6 +476,15 @@ void DatabaseWidget::openDatabase(bool accepted)
}
}
void DatabaseWidget::unlockDatabase(bool accepted)
{
// cancel button is disabled
Q_ASSERT(accepted);
setCurrentWidget(widgetBeforeLock);
Q_EMIT unlockedDatabase();
}
void DatabaseWidget::switchToEntryEdit()
{
switchToEntryEdit(m_entryView->currentEntry(), false);
@ -481,32 +498,35 @@ void DatabaseWidget::switchToGroupEdit()
void DatabaseWidget::switchToMasterKeyChange()
{
m_changeMasterKeyWidget->clearForms();
setCurrentIndex(3);
setCurrentWidget(m_changeMasterKeyWidget);
}
void DatabaseWidget::switchToDatabaseSettings()
{
m_databaseSettingsWidget->load(m_db);
setCurrentIndex(4);
setCurrentWidget(m_databaseSettingsWidget);
}
void DatabaseWidget::switchToOpenDatabase(const QString& fileName)
{
updateFilename(fileName);
m_databaseOpenWidget->load(fileName);
setCurrentIndex(6);
setCurrentWidget(m_databaseOpenWidget);
}
void DatabaseWidget::switchToOpenDatabase(const QString& fileName, const QString& password,
const QString& keyFile)
{
updateFilename(fileName);
switchToOpenDatabase(fileName);
m_databaseOpenWidget->enterKey(password, keyFile);
}
void DatabaseWidget::switchToImportKeepass1(const QString& fileName)
{
updateFilename(fileName);
m_keepass1OpenWidget->load(fileName);
setCurrentIndex(7);
setCurrentWidget(m_keepass1OpenWidget);
}
void DatabaseWidget::toggleSearch()
@ -641,3 +661,17 @@ void DatabaseWidget::clearLastGroup(Group* group)
m_searchWidget->hide();
}
}
void DatabaseWidget::lock()
{
Q_ASSERT(currentMode() != DatabaseWidget::LockedMode);
widgetBeforeLock = currentWidget();
m_unlockDatabaseWidget->load(m_filename, m_db);
setCurrentWidget(m_unlockDatabaseWidget);
}
void DatabaseWidget::updateFilename(const QString& fileName)
{
m_filename = fileName;
}

View File

@ -36,6 +36,7 @@ class GroupView;
class KeePass1OpenWidget;
class QFile;
class QMenu;
class UnlockDatabaseWidget;
namespace Ui {
class SearchWidget;
@ -50,7 +51,8 @@ public:
{
None,
ViewMode,
EditMode
EditMode,
LockedMode
};
explicit DatabaseWidget(Database* db, QWidget* parent = Q_NULLPTR);
@ -63,7 +65,10 @@ public:
bool isInSearchMode();
int addWidget(QWidget* w);
void setCurrentIndex(int index);
void setCurrentWidget(QWidget* widget);
DatabaseWidget::Mode currentMode();
void lock();
void updateFilename(const QString& filename);
Q_SIGNALS:
void closeRequest();
@ -73,6 +78,7 @@ Q_SIGNALS:
void databaseChanged(Database* newDb);
void groupContextMenuRequested(const QPoint& globalPos);
void entryContextMenuRequested(const QPoint& globalPos);
void unlockedDatabase();
public Q_SLOTS:
void createEntry();
@ -104,6 +110,7 @@ private Q_SLOTS:
void switchToGroupEdit(Group* entry, bool create);
void updateMasterKey(bool accepted);
void openDatabase(bool accepted);
void unlockDatabase(bool accepted);
void emitCurrentModeChanged();
void clearLastGroup(Group* group);
void search();
@ -124,6 +131,7 @@ private:
DatabaseSettingsWidget* m_databaseSettingsWidget;
DatabaseOpenWidget* m_databaseOpenWidget;
KeePass1OpenWidget* m_keepass1OpenWidget;
UnlockDatabaseWidget* m_unlockDatabaseWidget;
GroupView* m_groupView;
EntryView* m_entryView;
Group* m_newGroup;
@ -131,6 +139,8 @@ private:
Group* m_newParent;
Group* m_lastGroup;
QTimer* m_searchTimer;
QWidget* widgetBeforeLock;
QString m_filename;
};
#endif // KEEPASSX_DATABASEWIDGET_H

View File

@ -29,7 +29,7 @@
KeePass1OpenWidget::KeePass1OpenWidget(QWidget* parent)
: DatabaseOpenWidget(parent)
{
setWindowTitle(tr("Import KeePass1 database"));
m_ui->labelHeadline->setText(tr("Import KeePass1 database"));
}
void KeePass1OpenWidget::openDatabase()

View File

@ -63,6 +63,7 @@ MainWindow::MainWindow()
setShortcut(m_ui->actionDatabaseSave, QKeySequence::Save, Qt::CTRL + Qt::Key_S);
setShortcut(m_ui->actionDatabaseSaveAs, QKeySequence::SaveAs);
setShortcut(m_ui->actionDatabaseClose, QKeySequence::Close, Qt::CTRL + Qt::Key_W);
m_ui->actionLockDatabases->setShortcut(Qt::CTRL + Qt::Key_L);
setShortcut(m_ui->actionQuit, QKeySequence::Quit, Qt::CTRL + Qt::Key_Q);
setShortcut(m_ui->actionSearch, QKeySequence::Find, Qt::CTRL + Qt::Key_F);
m_ui->actionEntryNew->setShortcut(Qt::CTRL + Qt::Key_N);
@ -85,6 +86,7 @@ MainWindow::MainWindow()
m_ui->actionDatabaseClose->setIcon(filePath()->icon("actions", "document-close"));
m_ui->actionChangeDatabaseSettings->setIcon(filePath()->icon("actions", "document-edit"));
m_ui->actionChangeMasterKey->setIcon(filePath()->icon("actions", "database-change-key", false));
m_ui->actionLockDatabases->setIcon(filePath()->icon("actions", "document-encrypt", false));
m_ui->actionQuit->setIcon(filePath()->icon("actions", "application-exit"));
m_ui->actionEntryNew->setIcon(filePath()->icon("actions", "entry-new", false));
@ -140,6 +142,8 @@ MainWindow::MainWindow()
SLOT(changeDatabaseSettings()));
connect(m_ui->actionImportKeePass1, SIGNAL(triggered()), m_ui->tabWidget,
SLOT(importKeePass1Database()));
connect(m_ui->actionLockDatabases, SIGNAL(triggered()), m_ui->tabWidget,
SLOT(lockDatabases()));
connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(close()));
m_actionMultiplexer.connect(m_ui->actionEntryNew, SIGNAL(triggered()),
@ -246,6 +250,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
break;
}
case DatabaseWidget::EditMode:
case DatabaseWidget::LockedMode:
Q_FOREACH (QAction* action, m_ui->menuEntries->actions()) {
action->setEnabled(false);
}
@ -290,6 +295,8 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionImportKeePass1->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionLockDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
}
void MainWindow::updateWindowTitle()

View File

@ -94,6 +94,7 @@
<addaction name="separator"/>
<addaction name="actionImportKeePass1"/>
<addaction name="separator"/>
<addaction name="actionLockDatabases"/>
<addaction name="actionQuit"/>
</widget>
<widget class="QMenu" name="menuHelp">
@ -328,6 +329,14 @@
<string>Open URL</string>
</property>
</action>
<action name="actionLockDatabases">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Lock databases</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

View File

@ -0,0 +1,64 @@
/*
* 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 "UnlockDatabaseWidget.h"
#include <QtGui/QMessageBox>
#include "ui_DatabaseOpenWidget.h"
#include "core/Database.h"
UnlockDatabaseWidget::UnlockDatabaseWidget(QWidget* parent)
: DatabaseOpenWidget(parent)
{
m_ui->labelHeadline->setText(tr("Unlock database"));
m_ui->buttonBox->removeButton(m_ui->buttonBox->button(QDialogButtonBox::Cancel));
connect(this, SIGNAL(editFinished(bool)), SLOT(clearForms()));
}
void UnlockDatabaseWidget::load(const QString& filename, Database* db)
{
Q_ASSERT(db);
DatabaseOpenWidget::load(filename);
m_db = db;
}
void UnlockDatabaseWidget::openDatabase()
{
CompositeKey masterKey = databaseKey();
if (masterKey.isEmpty()) {
return;
}
if (m_db->verifyKey(masterKey)) {
Q_EMIT editFinished(true);
}
else {
QMessageBox::warning(this, tr("Error"), tr("Wrong key."));
m_ui->editPassword->clear();
}
}
void UnlockDatabaseWidget::clearForms()
{
m_ui->editPassword->clear();
m_ui->comboKeyFile->clear();
m_ui->checkPassword->setChecked(false);
m_ui->checkKeyFile->setChecked(false);
}

View File

@ -0,0 +1,33 @@
/*
* 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 "gui/DatabaseOpenWidget.h"
class UnlockDatabaseWidget : public DatabaseOpenWidget
{
Q_OBJECT
public:
explicit UnlockDatabaseWidget(QWidget* parent = Q_NULLPTR);
void load(const QString& filename, Database* db);
protected:
void openDatabase() Q_DECL_OVERRIDE;
private Q_SLOTS:
void clearForms();
};

View File

@ -336,6 +336,24 @@ void TestGui::testKeePass1Import()
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("basic [New database]*"));
}
void TestGui::testDatabaseLocking()
{
triggerAction("actionLockDatabases");
QCOMPARE(m_tabWidget->tabText(0), QString("Save [locked]"));
QCOMPARE(m_tabWidget->tabText(1), QString("basic [New database] [locked]*"));
QWidget* dbWidget = m_tabWidget->currentDatabaseWidget();
QWidget* unlockDatabaseWidget = dbWidget->findChild<QWidget*>("unlockDatabaseWidget");
QWidget* editPassword = unlockDatabaseWidget->findChild<QLineEdit*>("editPassword");
QVERIFY(editPassword);
QTest::keyClicks(editPassword, "masterpw");
QTest::keyClick(editPassword, Qt::Key_Enter);
QCOMPARE(m_tabWidget->tabText(m_tabWidget->currentIndex()), QString("basic [New database]*"));
}
void TestGui::cleanupTestCase()
{
delete m_mainWindow;

View File

@ -45,6 +45,7 @@ private Q_SLOTS:
void testSave();
void testDatabaseSettings();
void testKeePass1Import();
void testDatabaseLocking();
void cleanupTestCase();
private: