Cleanup and replumb back to functional state

This commit is contained in:
Jonathan White 2018-12-19 17:52:12 -05:00 committed by Jonathan White
parent 9e2be34897
commit b96b86bfa7
14 changed files with 143 additions and 234 deletions

View File

@ -4,9 +4,9 @@ if(WITH_XC_CRYPTO_SSH)
set(crypto_ssh_SOURCES set(crypto_ssh_SOURCES
bcrypt_pbkdf.cpp bcrypt_pbkdf.cpp
blowfish.c blowfish.c
ASN1Key.cpp ASN1Key.cpp
BinaryStream.cpp BinaryStream.cpp
OpenSSHKey.cpp OpenSSHKey.cpp
) )
add_library(crypto_ssh STATIC ${crypto_ssh_SOURCES}) add_library(crypto_ssh STATIC ${crypto_ssh_SOURCES})

View File

@ -78,16 +78,17 @@ ApplicationSettingsWidget::ApplicationSettingsWidget(QWidget* parent)
connect(this, SIGNAL(apply()), SLOT(saveSettings())); connect(this, SIGNAL(apply()), SLOT(saveSettings()));
connect(this, SIGNAL(rejected()), SLOT(reject())); connect(this, SIGNAL(rejected()), SLOT(reject()));
connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableAutoSaveOnExit(bool))); // clang-format off
connect(m_generalUi->autoSaveAfterEveryChangeCheckBox, SIGNAL(toggled(bool)), SLOT(enableAutoSaveOnExit(bool)));
connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableSystray(bool))); connect(m_generalUi->systrayShowCheckBox, SIGNAL(toggled(bool)), this, SLOT(enableSystray(bool)));
connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)), m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool))); connect(m_secUi->clearClipboardCheckBox, SIGNAL(toggled(bool)),
connect(m_secUi->lockDatabaseIdleCheckBox, m_secUi->clearClipboardSpinBox, SLOT(setEnabled(bool)));
SIGNAL(toggled(bool)), connect(m_secUi->lockDatabaseIdleCheckBox, SIGNAL(toggled(bool)),
m_secUi->lockDatabaseIdleSpinBox, m_secUi->lockDatabaseIdleSpinBox, SLOT(setEnabled(bool)));
SLOT(setEnabled(bool))); connect(m_secUi->touchIDResetCheckBox, SIGNAL(toggled(bool)),
m_secUi->touchIDResetSpinBox, SLOT(setEnabled(bool)));
connect(m_secUi->touchIDResetCheckBox, SIGNAL(toggled(bool)), m_secUi->touchIDResetSpinBox, SLOT(setEnabled(bool))); // clang-format on
#ifndef WITH_XC_NETWORKING #ifndef WITH_XC_NETWORKING
m_secUi->privacy->setVisible(false); m_secUi->privacy->setVisible(false);

View File

@ -58,6 +58,7 @@
#include "gui/entry/EntryView.h" #include "gui/entry/EntryView.h"
#include "gui/group/EditGroupWidget.h" #include "gui/group/EditGroupWidget.h"
#include "gui/group/GroupView.h" #include "gui/group/GroupView.h"
#include "keeshare/KeeShare.h"
#include "touchid/TouchID.h" #include "touchid/TouchID.h"
#include "config-keepassx.h" #include "config-keepassx.h"
@ -372,6 +373,9 @@ void DatabaseWidget::replaceDatabase(QSharedPointer<Database> db)
connectDatabaseSignals(); connectDatabaseSignals();
m_groupView->changeDatabase(m_db); m_groupView->changeDatabase(m_db);
processAutoOpen(); processAutoOpen();
#ifdef WITH_XC_KEESHARE
KeeShare::instance()->connectDatabase(m_db, oldDb);
#endif
} }
void DatabaseWidget::cloneEntry() void DatabaseWidget::cloneEntry()

View File

@ -161,12 +161,16 @@ MainWindow::MainWindow()
#ifdef WITH_XC_KEESHARE #ifdef WITH_XC_KEESHARE
KeeShare::init(this); KeeShare::init(this);
m_ui->settingsWidget->addSettingsPage(new SettingsPageKeeShare(m_ui->tabWidget)); m_ui->settingsWidget->addSettingsPage(new SettingsPageKeeShare(m_ui->tabWidget));
connect(KeeShare::instance(), SIGNAL(sharingMessage(QString, MessageWidget::MessageType)),
SLOT(displayGlobalMessage(QString, MessageWidget::MessageType)));
#endif #endif
setWindowIcon(filePath()->applicationIcon()); setWindowIcon(filePath()->applicationIcon());
m_ui->globalMessageWidget->setHidden(true); m_ui->globalMessageWidget->setHidden(true);
// clang-format off
connect(m_ui->globalMessageWidget, &MessageWidget::linkActivated, &MessageWidget::openHttpUrl); connect(m_ui->globalMessageWidget, &MessageWidget::linkActivated, &MessageWidget::openHttpUrl);
connect(m_ui->globalMessageWidget, SIGNAL(showAnimationStarted()), m_ui->globalMessageWidgetContainer, SLOT(show())); connect(m_ui->globalMessageWidget, SIGNAL(showAnimationStarted()), m_ui->globalMessageWidgetContainer, SLOT(show()));
connect(m_ui->globalMessageWidget, SIGNAL(hideAnimationFinished()), m_ui->globalMessageWidgetContainer, SLOT(hide())); connect(m_ui->globalMessageWidget, SIGNAL(hideAnimationFinished()), m_ui->globalMessageWidgetContainer, SLOT(hide()));
// clang-format on
m_clearHistoryAction = new QAction(tr("Clear history"), m_ui->menuFile); m_clearHistoryAction = new QAction(tr("Clear history"), m_ui->menuFile);
m_lastDatabasesActions = new QActionGroup(m_ui->menuRecentDatabases); m_lastDatabasesActions = new QActionGroup(m_ui->menuRecentDatabases);

View File

@ -63,6 +63,9 @@ EditGroupWidget::EditGroupWidget(QWidget* parent)
addPage(tr("Group"), FilePath::instance()->icon("actions", "document-edit"), m_editGroupWidgetMain); addPage(tr("Group"), FilePath::instance()->icon("actions", "document-edit"), m_editGroupWidgetMain);
addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_editGroupWidgetIcons); addPage(tr("Icon"), FilePath::instance()->icon("apps", "preferences-desktop-icons"), m_editGroupWidgetIcons);
#ifdef WITH_XC_KEESHARE
addEditPage(new EditGroupPageKeeShare(this));
#endif
addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties); addPage(tr("Properties"), FilePath::instance()->icon("actions", "document-properties"), m_editWidgetProperties);
connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool))); connect(m_mainUi->expireCheck, SIGNAL(toggled(bool)), m_mainUi->expireDatePicker, SLOT(setEnabled(bool)));
@ -82,10 +85,6 @@ EditGroupWidget::EditGroupWidget(QWidget* parent)
// clang-format on // clang-format on
connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage())); connect(m_editGroupWidgetIcons, SIGNAL(messageEditEntryDismiss()), SLOT(hideMessage()));
#ifdef WITH_XC_KEESHARE
addEditPage(new EditGroupPageKeeShare(this));
#endif
} }
EditGroupWidget::~EditGroupWidget() EditGroupWidget::~EditGroupWidget()

View File

@ -82,7 +82,6 @@ private:
QPointer<EditWidgetProperties> m_editWidgetProperties; QPointer<EditWidgetProperties> m_editWidgetProperties;
QScopedPointer<Group> m_temporaryGroup; QScopedPointer<Group> m_temporaryGroup;
QPointer<Database> m_database;
QPointer<Group> m_group; QPointer<Group> m_group;
QSharedPointer<Database> m_db; QSharedPointer<Database> m_db;

View File

@ -32,10 +32,10 @@
namespace namespace
{ {
static const QString KeeShare_Reference("KeeShare/Reference"); static const QString KeeShare_Reference("KeeShare/Reference");
static const QString KeeShare_Own("KeeShare/Settings.own"); static const QString KeeShare_Own("KeeShare/Settings.own");
static const QString KeeShare_Foreign("KeeShare/Settings.foreign"); static const QString KeeShare_Foreign("KeeShare/Settings.foreign");
static const QString KeeShare_Active("KeeShare/Settings.active"); static const QString KeeShare_Active("KeeShare/Settings.active");
} }
KeeShare* KeeShare::m_instance = nullptr; KeeShare* KeeShare::m_instance = nullptr;
@ -49,6 +49,12 @@ KeeShare* KeeShare::instance()
return m_instance; return m_instance;
} }
KeeShare::KeeShare(QObject* parent)
: QObject(parent)
{
connect(config(), SIGNAL(changed(QString)), SLOT(handleSettingsChanged(QString)));
}
void KeeShare::init(QObject* parent) void KeeShare::init(QObject* parent)
{ {
Q_ASSERT(!m_instance); Q_ASSERT(!m_instance);
@ -162,61 +168,19 @@ QString KeeShare::indicatorSuffix(const Group* group, const QString& text)
void KeeShare::connectDatabase(QSharedPointer<Database> newDb, QSharedPointer<Database> oldDb) void KeeShare::connectDatabase(QSharedPointer<Database> newDb, QSharedPointer<Database> oldDb)
{ {
if (oldDb && m_observersByDatabase.contains(oldDb.data())) { if (oldDb && m_observersByDatabase.contains(oldDb->uuid())) {
QPointer<ShareObserver> observer = m_observersByDatabase.take(oldDb.data()); QPointer<ShareObserver> observer = m_observersByDatabase.take(oldDb->uuid());
if (observer) { if (observer) {
delete observer; delete observer;
} }
} }
if (newDb && !m_observersByDatabase.contains(newDb.data())) { if (newDb && !m_observersByDatabase.contains(newDb->uuid())) {
QPointer<ShareObserver> observer(new ShareObserver(newDb, this)); QPointer<ShareObserver> observer(new ShareObserver(newDb, this));
m_observersByDatabase[newDb.data()] = observer; m_observersByDatabase[newDb->uuid()] = observer;
connect(observer.data(), connect(observer.data(),
SIGNAL(sharingMessage(QString, MessageWidget::MessageType)), SIGNAL(sharingMessage(QString, MessageWidget::MessageType)),
this, SIGNAL(sharingMessage(QString, MessageWidget::MessageType)));
SLOT(emitSharingMessage(QString, MessageWidget::MessageType)));
}
}
void KeeShare::handleDatabaseOpened(QSharedPointer<Database> db)
{
QPointer<ShareObserver> observer = m_observersByDatabase.value(db.data());
if (observer) {
observer->handleDatabaseOpened();
}
}
void KeeShare::handleDatabaseSaved(QSharedPointer<Database> db)
{
QPointer<ShareObserver> observer = m_observersByDatabase.value(db.data());
if (observer) {
observer->handleDatabaseSaved();
}
}
void KeeShare::emitSharingMessage(const QString& message, KMessageWidget::MessageType type)
{
QObject* observer = sender();
auto db = m_databasesByObserver.value(observer);
if (db) {
emit sharingMessage(db, message, type);
}
}
void KeeShare::handleDatabaseDeleted(QObject* db)
{
auto observer = m_observersByDatabase.take(db);
if (observer) {
m_databasesByObserver.remove(observer);
}
}
void KeeShare::handleObserverDeleted(QObject* observer)
{
auto database = m_databasesByObserver.take(observer);
if (database) {
m_observersByDatabase.remove(database.data());
} }
} }
@ -226,9 +190,3 @@ void KeeShare::handleSettingsChanged(const QString& key)
emit activeChanged(); emit activeChanged();
} }
} }
KeeShare::KeeShare(QObject* parent)
: QObject(parent)
{
connect(config(), SIGNAL(changed(QString)), this, SLOT(handleSettingsChanged(QString)));
}

View File

@ -19,7 +19,7 @@
#define KEEPASSXC_KEESHARE_H #define KEEPASSXC_KEESHARE_H
#include <QMap> #include <QMap>
#include <QObject> #include <QUuid>
#include "gui/MessageWidget.h" #include "gui/MessageWidget.h"
#include "keeshare/KeeShareSettings.h" #include "keeshare/KeeShareSettings.h"
@ -32,7 +32,7 @@ class QXmlStreamReader;
class KeeShare : public QObject class KeeShare : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static KeeShare* instance(); static KeeShare* instance();
static void init(QObject* parent); static void init(QObject* parent);
@ -54,17 +54,12 @@ public:
static QString referenceTypeLabel(const KeeShareSettings::Reference& reference); static QString referenceTypeLabel(const KeeShareSettings::Reference& reference);
void connectDatabase(QSharedPointer<Database> newDb, QSharedPointer<Database> oldDb); void connectDatabase(QSharedPointer<Database> newDb, QSharedPointer<Database> oldDb);
void handleDatabaseOpened(QSharedPointer<Database> db);
void handleDatabaseSaved(QSharedPointer<Database> db);
signals: signals:
void activeChanged(); void activeChanged();
void sharingMessage(QSharedPointer<Database>, QString, MessageWidget::MessageType); void sharingMessage(QString, MessageWidget::MessageType);
private slots: private slots:
void emitSharingMessage(const QString&, MessageWidget::MessageType);
void handleDatabaseDeleted(QObject*);
void handleObserverDeleted(QObject*);
void handleSettingsChanged(const QString&); void handleSettingsChanged(const QString&);
private: private:
@ -72,8 +67,7 @@ private:
explicit KeeShare(QObject* parent); explicit KeeShare(QObject* parent);
QMap<QObject*, QPointer<ShareObserver>> m_observersByDatabase; QMap<QUuid, QPointer<ShareObserver>> m_observersByDatabase;
QMap<QObject*, QSharedPointer<Database>> m_databasesByObserver;
}; };
#endif // KEEPASSXC_KEESHARE_H #endif // KEEPASSXC_KEESHARE_H

View File

@ -95,10 +95,6 @@ void SettingsWidgetKeeShare::saveSettings()
// TODO HNH: This depends on the order of saving new data - a better model would be to // TODO HNH: This depends on the order of saving new data - a better model would be to
// store changes to the settings in a temporary object and check on the final values // store changes to the settings in a temporary object and check on the final values
// of this object (similar scheme to Entry) - this way we could validate the settings before save // of this object (similar scheme to Entry) - this way we could validate the settings before save
if (active.in) {
emit settingsMessage(tr("Make sure to have a history size greater than 2 to prevent data loss when importing!"), MessageWidget::Warning);
}
KeeShare::setOwn(m_own); KeeShare::setOwn(m_own);
KeeShare::setForeign(m_foreign); KeeShare::setForeign(m_foreign);
KeeShare::setActive(active); KeeShare::setActive(active);

View File

@ -48,84 +48,96 @@
namespace namespace
{ {
static const QString KeeShare_Signature("container.share.signature"); static const QString KeeShare_Signature("container.share.signature");
static const QString KeeShare_Container("container.share.kdbx"); static const QString KeeShare_Container("container.share.kdbx");
enum Trust enum Trust
{ {
None, None,
Invalid, Invalid,
Single, Single,
Lasting, Lasting,
Known, Known,
Own Own
}; };
QPair<Trust, KeeShareSettings::Certificate> check(QByteArray& data,
const KeeShareSettings::Reference& reference,
const KeeShareSettings::Certificate& ownCertificate,
const QList<KeeShareSettings::Certificate>& knownCertificates,
const KeeShareSettings::Sign& sign)
{
if (sign.signature.isEmpty()) {
QMessageBox warning;
warning.setIcon(QMessageBox::Warning);
warning.setWindowTitle(ShareObserver::tr("Untrustworthy container without signature"));
warning.setText(ShareObserver::tr("Do you want to import from unsigned container %1").arg(reference.path));
auto yes = warning.addButton(ShareObserver::tr("Import once"), QMessageBox::ButtonRole::YesRole);
auto no = warning.addButton(ShareObserver::tr("No"), QMessageBox::ButtonRole::NoRole);
warning.setDefaultButton(no);
warning.exec();
const auto trust = warning.clickedButton() == yes ? Single : None;
return qMakePair(trust, KeeShareSettings::Certificate());
}
auto key = sign.certificate.sshKey();
key.openKey(QString());
const Signature signer;
if (!signer.verify(data, sign.signature, key)) {
const QFileInfo info(reference.path);
qCritical("Invalid signature for sharing container %s.", qPrintable(info.absoluteFilePath()));
return qMakePair(Invalid, KeeShareSettings::Certificate());
}
if (ownCertificate.key == sign.certificate.key) {
return qMakePair(Own, ownCertificate);
}
for (const auto& certificate : knownCertificates) {
if (certificate.key == certificate.key && certificate.trusted) {
return qMakePair(Known, certificate);
}
}
QPair<Trust, KeeShareSettings::Certificate> check(QByteArray& data,
const KeeShareSettings::Reference& reference,
const KeeShareSettings::Certificate& ownCertificate,
const QList<KeeShareSettings::Certificate>& knownCertificates,
const KeeShareSettings::Sign& sign)
{
if (sign.signature.isEmpty()) {
QMessageBox warning; QMessageBox warning;
warning.setIcon(QMessageBox::Question); warning.setIcon(QMessageBox::Warning);
warning.setWindowTitle(ShareObserver::tr("Import from untrustworthy certificate for sharing container")); warning.setWindowTitle(ShareObserver::tr("Untrustworthy container without signature"));
warning.setText(ShareObserver::tr("Do you want to trust %1 with the fingerprint of %2") warning.setText(ShareObserver::tr("Do you want to import from unsigned container %1").arg(reference.path));
.arg(sign.certificate.signer) auto yes = warning.addButton(ShareObserver::tr("Import once"), QMessageBox::ButtonRole::YesRole);
.arg(sign.certificate.fingerprint()));
auto yes = warning.addButton(ShareObserver::tr("Import and trust"), QMessageBox::ButtonRole::YesRole);
auto no = warning.addButton(ShareObserver::tr("No"), QMessageBox::ButtonRole::NoRole); auto no = warning.addButton(ShareObserver::tr("No"), QMessageBox::ButtonRole::NoRole);
warning.setDefaultButton(no); warning.setDefaultButton(no);
warning.exec(); warning.exec();
if (warning.clickedButton() != yes) { const auto trust = warning.clickedButton() == yes ? Single : None;
qWarning("Prevented import due to untrusted certificate of %s", qPrintable(sign.certificate.signer)); return qMakePair(trust, KeeShareSettings::Certificate());
return qMakePair(None, sign.certificate);
}
return qMakePair(Lasting, sign.certificate);
} }
auto key = sign.certificate.sshKey();
key.openKey(QString());
const Signature signer;
if (!signer.verify(data, sign.signature, key)) {
const QFileInfo info(reference.path);
qCritical("Invalid signature for sharing container %s.", qPrintable(info.absoluteFilePath()));
return qMakePair(Invalid, KeeShareSettings::Certificate());
}
if (ownCertificate.key == sign.certificate.key) {
return qMakePair(Own, ownCertificate);
}
for (const auto& certificate : knownCertificates) {
if (certificate.key == certificate.key && certificate.trusted) {
return qMakePair(Known, certificate);
}
}
QMessageBox warning;
warning.setIcon(QMessageBox::Question);
warning.setWindowTitle(ShareObserver::tr("Import from untrustworthy certificate for sharing container"));
warning.setText(ShareObserver::tr("Do you want to trust %1 with the fingerprint of %2")
.arg(sign.certificate.signer)
.arg(sign.certificate.fingerprint()));
auto yes = warning.addButton(ShareObserver::tr("Import and trust"), QMessageBox::ButtonRole::YesRole);
auto no = warning.addButton(ShareObserver::tr("No"), QMessageBox::ButtonRole::NoRole);
warning.setDefaultButton(no);
warning.exec();
if (warning.clickedButton() != yes) {
qWarning("Prevented import due to untrusted certificate of %s", qPrintable(sign.certificate.signer));
return qMakePair(None, sign.certificate);
}
return qMakePair(Lasting, sign.certificate);
} }
} // End Namespace
ShareObserver::ShareObserver(QSharedPointer<Database> db, QObject* parent) ShareObserver::ShareObserver(QSharedPointer<Database> db, QObject* parent)
: QObject(parent) : QObject(parent)
, m_db(std::move(db)) , m_db(std::move(db))
, m_fileWatcher(new BulkFileWatcher(this)) , m_fileWatcher(new BulkFileWatcher(this))
{ {
connect(KeeShare::instance(), SIGNAL(activeChanged()), this, SLOT(handleDatabaseChanged())); connect(KeeShare::instance(), SIGNAL(activeChanged()), SLOT(handleDatabaseChanged()));
connect(m_db.data(), SIGNAL(modified()), this, SLOT(handleDatabaseChanged())); connect(m_db.data(), SIGNAL(modified()), SLOT(handleDatabaseChanged()));
connect(m_db.data(), SIGNAL(databaseSaved()), SLOT(handleDatabaseSaved()));
connect(m_fileWatcher, SIGNAL(fileCreated(QString)), this, SLOT(handleFileCreated(QString))); connect(m_fileWatcher, SIGNAL(fileCreated(QString)), SLOT(handleFileUpdated(QString)));
connect(m_fileWatcher, SIGNAL(fileChanged(QString)), this, SLOT(handleFileChanged(QString))); connect(m_fileWatcher, SIGNAL(fileChanged(QString)), SLOT(handleFileUpdated(QString)));
connect(m_fileWatcher, SIGNAL(fileRemoved(QString)), this, SLOT(handleFileRemoved(QString))); connect(m_fileWatcher, SIGNAL(fileRemoved(QString)), SLOT(handleFileUpdated(QString)));
const auto active = KeeShare::active();
if (!active.in && !active.out) {
deinitialize();
} else {
reinitialize();
}
} }
ShareObserver::~ShareObserver() ShareObserver::~ShareObserver()
@ -147,6 +159,7 @@ void ShareObserver::reinitialize()
KeeShareSettings::Reference oldReference; KeeShareSettings::Reference oldReference;
KeeShareSettings::Reference newReference; KeeShareSettings::Reference newReference;
}; };
const auto active = KeeShare::active(); const auto active = KeeShare::active();
QList<Update> updated; QList<Update> updated;
QList<Group*> groups = m_db->rootGroup()->groupsRecursive(true); QList<Group*> groups = m_db->rootGroup()->groupsRecursive(true);
@ -155,6 +168,7 @@ void ShareObserver::reinitialize()
if (couple.oldReference == couple.newReference) { if (couple.oldReference == couple.newReference) {
continue; continue;
} }
m_groupToReference.remove(couple.group); m_groupToReference.remove(couple.group);
m_referenceToGroup.remove(couple.oldReference); m_referenceToGroup.remove(couple.oldReference);
m_shareToGroup.remove(couple.oldReference.path); m_shareToGroup.remove(couple.oldReference.path);
@ -174,6 +188,7 @@ void ShareObserver::reinitialize()
if (!update.oldReference.path.isEmpty()) { if (!update.oldReference.path.isEmpty()) {
m_fileWatcher->removePath(update.oldReference.path); m_fileWatcher->removePath(update.oldReference.path);
} }
if (!update.newReference.path.isEmpty() && update.newReference.type != KeeShareSettings::Inactive) { if (!update.newReference.path.isEmpty() && update.newReference.type != KeeShareSettings::Inactive) {
m_fileWatcher->addPath(update.newReference.path); m_fileWatcher->addPath(update.newReference.path);
} }
@ -196,6 +211,7 @@ void ShareObserver::reinitialize()
} }
} }
} }
notifyAbout(success, warning, error); notifyAbout(success, warning, error);
} }
@ -229,20 +245,8 @@ void ShareObserver::handleDatabaseChanged()
} }
} }
void ShareObserver::handleFileUpdated(const QString& path, Change change) void ShareObserver::handleFileUpdated(const QString& path)
{ {
switch (change) {
case Creation:
qDebug("File created %s", qPrintable(path));
break;
case Update:
qDebug("File changed %s", qPrintable(path));
break;
case Deletion:
qDebug("File deleted %s", qPrintable(path));
break;
}
const Result result = this->importFromReferenceContainer(path); const Result result = this->importFromReferenceContainer(path);
if (!result.isValid()) { if (!result.isValid()) {
return; return;
@ -262,21 +266,6 @@ void ShareObserver::handleFileUpdated(const QString& path, Change change)
notifyAbout(success, warning, error); notifyAbout(success, warning, error);
} }
void ShareObserver::handleFileCreated(const QString& path)
{
handleFileUpdated(path, Creation);
}
void ShareObserver::handleFileChanged(const QString& path)
{
handleFileUpdated(path, Update);
}
void ShareObserver::handleFileRemoved(const QString& path)
{
handleFileUpdated(path, Deletion);
}
ShareObserver::Result ShareObserver::importContainerInto(const KeeShareSettings::Reference& reference, Group* targetGroup) ShareObserver::Result ShareObserver::importContainerInto(const KeeShareSettings::Reference& reference, Group* targetGroup)
{ {
const QFileInfo info(reference.path); const QFileInfo info(reference.path);
@ -471,30 +460,11 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference&
return targetDb; return targetDb;
} }
const QSharedPointer<Database> ShareObserver::database() const
{
return m_db;
}
QSharedPointer<Database> ShareObserver::database() QSharedPointer<Database> ShareObserver::database()
{ {
return m_db; return m_db;
} }
void ShareObserver::handleDatabaseOpened()
{
if (!m_db) {
Q_ASSERT(m_db);
return;
}
const auto active = KeeShare::active();
if (!active.in && !active.out) {
deinitialize();
} else {
reinitialize();
}
}
QList<ShareObserver::Result> ShareObserver::exportIntoReferenceContainers() QList<ShareObserver::Result> ShareObserver::exportIntoReferenceContainers()
{ {
QList<Result> results; QList<Result> results;

View File

@ -35,37 +35,23 @@ class Database;
class ShareObserver : public QObject class ShareObserver : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ShareObserver(QSharedPointer<Database> db, QObject* parent = nullptr); explicit ShareObserver(QSharedPointer<Database> db, QObject* parent = nullptr);
~ShareObserver(); ~ShareObserver();
void handleDatabaseSaved();
void handleDatabaseOpened();
const QSharedPointer<Database> database() const;
QSharedPointer<Database> database(); QSharedPointer<Database> database();
signals: signals:
void sharingMessage(QString, MessageWidget::MessageType); void sharingMessage(QString, MessageWidget::MessageType);
public slots:
void handleDatabaseChanged();
private slots: private slots:
void handleFileCreated(const QString& path); void handleDatabaseChanged();
void handleFileChanged(const QString& path); void handleDatabaseSaved();
void handleFileRemoved(const QString& path); void handleFileUpdated(const QString& path);
private: private:
enum Change
{
Creation,
Update,
Deletion
};
struct Result struct Result
{ {
enum Type enum Type
@ -97,7 +83,6 @@ private:
QList<ShareObserver::Result> exportIntoReferenceContainers(); QList<ShareObserver::Result> exportIntoReferenceContainers();
void deinitialize(); void deinitialize();
void reinitialize(); void reinitialize();
void handleFileUpdated(const QString& path, Change change);
void notifyAbout(const QStringList& success, const QStringList& warning, const QStringList& error); void notifyAbout(const QStringList& success, const QStringList& warning, const QStringList& error);
private: private:

View File

@ -55,10 +55,10 @@ EditGroupWidgetKeeShare::EditGroupWidgetKeeShare(QWidget* parent)
connect(KeeShare::instance(), SIGNAL(activeChanged()), SLOT(showSharingState())); connect(KeeShare::instance(), SIGNAL(activeChanged()), SLOT(showSharingState()));
const auto types = QList<KeeShareSettings::Type>() << KeeShareSettings::Inactive const auto types = QList<KeeShareSettings::Type>() << KeeShareSettings::Inactive
<< KeeShareSettings::ImportFrom << KeeShareSettings::ImportFrom
<< KeeShareSettings::ExportTo << KeeShareSettings::ExportTo
<< KeeShareSettings::SynchronizeWith; << KeeShareSettings::SynchronizeWith;
for (const auto& type : types) { for (const auto& type : types) {
QString name; QString name;
switch (type) { switch (type) {
@ -121,7 +121,6 @@ void EditGroupWidgetKeeShare::update()
m_ui->pathEdit->clear(); m_ui->pathEdit->clear();
m_ui->passwordGenerator->hide(); m_ui->passwordGenerator->hide();
m_ui->togglePasswordGeneratorButton->setChecked(false); m_ui->togglePasswordGeneratorButton->setChecked(false);
} else { } else {
const auto reference = KeeShare::referenceOf(m_temporaryGroup); const auto reference = KeeShare::referenceOf(m_temporaryGroup);
@ -179,14 +178,9 @@ void EditGroupWidgetKeeShare::selectPath()
} }
switch (reference.type) { switch (reference.type) {
case KeeShareSettings::ImportFrom: case KeeShareSettings::ImportFrom:
filename = fileDialog()->getFileName(this, filename = fileDialog()->getFileName(
tr("Select import source"), this, tr("Select import source"), defaultDirPath, filters, nullptr, QFileDialog::DontConfirmOverwrite,
defaultDirPath, filetype, filename);
filters,
nullptr,
QFileDialog::DontConfirmOverwrite,
filetype,
filename);
break; break;
case KeeShareSettings::ExportTo: case KeeShareSettings::ExportTo:
filename = fileDialog()->getFileName( filename = fileDialog()->getFileName(
@ -203,7 +197,7 @@ void EditGroupWidgetKeeShare::selectPath()
return; return;
} }
setPath(filename); m_ui->pathEdit->setText(filename);
config()->set("KeeShare/LastShareDir", QFileInfo(filename).absolutePath()); config()->set("KeeShare/LastShareDir", QFileInfo(filename).absolutePath());
} }

View File

@ -9,5 +9,5 @@ if(WITH_XC_SSHAGENT)
) )
add_library(sshagent STATIC ${sshagent_SOURCES}) add_library(sshagent STATIC ${sshagent_SOURCES})
target_link_libraries(sshagent Qt5::Core Qt5::Widgets Qt5::Network ${GCRYPT_LIBRARIES} ${crypto_ssh_LIB}) target_link_libraries(sshagent Qt5::Core Qt5::Widgets Qt5::Network ${GCRYPT_LIBRARIES} ${crypto_ssh_LIB})
endif() endif()

View File

@ -99,7 +99,12 @@ set(TEST_LIBRARIES
${GPGERROR_LIBRARIES} ${GPGERROR_LIBRARIES}
${ZLIB_LIBRARIES}) ${ZLIB_LIBRARIES})
set(testsupport_SOURCES TestGlobal.h modeltest.cpp FailDevice.cpp mock/MockClock.cpp util/TemporaryFile.cpp stub/TestRandom.cpp) set(testsupport_SOURCES
modeltest.cpp
FailDevice.cpp
mock/MockClock.cpp
util/TemporaryFile.cpp
stub/TestRandom.cpp)
add_library(testsupport STATIC ${testsupport_SOURCES}) add_library(testsupport STATIC ${testsupport_SOURCES})
target_link_libraries(testsupport Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test) target_link_libraries(testsupport Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Test)