Skip to content

Commit

Permalink
Browser connection keys and rules are stored in custom data instead o…
Browse files Browse the repository at this point in the history
…f attributes
  • Loading branch information
varjolintu committed Feb 28, 2018
1 parent c167a0d commit 60d8670
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/browser/BrowserEntryConfig.cpp
Expand Up @@ -83,7 +83,7 @@ void BrowserEntryConfig::setRealm(const QString& realm)

bool BrowserEntryConfig::load(const Entry* entry)
{
QString s = entry->attributes()->value(KEEPASSBROWSER_NAME);
QString s = entry->customData()->value(KEEPASSBROWSER_NAME);
if (s.isEmpty()) {
return false;
}
Expand All @@ -105,5 +105,5 @@ void BrowserEntryConfig::save(Entry* entry)
QVariantMap v = qo2qv(this);
QJsonObject o = QJsonObject::fromVariantMap(v);
QByteArray json = QJsonDocument(o).toJson(QJsonDocument::Compact);
entry->attributes()->set(KEEPASSBROWSER_NAME, json);
entry->customData()->set(KEEPASSBROWSER_NAME, json);
}
68 changes: 65 additions & 3 deletions src/browser/BrowserOptionDialog.cpp
Expand Up @@ -23,14 +23,23 @@
#include "BrowserSettings.h"
#include "core/FilePath.h"

#include <QMessageBox>
#include <QFileDialog>
#include "gui/MessageBox.h"

BrowserOptionDialog::BrowserOptionDialog(QWidget* parent) :
BrowserOptionDialog::BrowserOptionDialog(DatabaseTabWidget* parent) :
QWidget(parent),
m_ui(new Ui::BrowserOptionDialog())
m_ui(new Ui::BrowserOptionDialog()),
m_customData(new CustomData(this)),
m_customDataModel(new QStandardItemModel(this)),
m_dbTabWidget(parent)
{
m_ui->setupUi(this);
m_ui->removeCustomDataButton->setEnabled(false);
m_ui->customDataTable->setModel(m_customDataModel);
connect(m_ui->customDataTable->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)),
SLOT(toggleRemoveButton(QItemSelection)));
connect(m_ui->removeCustomDataButton, SIGNAL(clicked()), SLOT(removeSelectedKey()));

connect(m_ui->removeSharedEncryptionKeys, SIGNAL(clicked()), this, SIGNAL(removeSharedEncryptionKeys()));
connect(m_ui->removeStoredPermissions, SIGNAL(clicked()), this, SIGNAL(removeStoredPermissions()));

Expand All @@ -54,6 +63,17 @@ BrowserOptionDialog::~BrowserOptionDialog()
{
}

CustomData* BrowserOptionDialog::customData() const
{
// Returns the current database customData from metadata. Otherwise return an empty customData member.
if (DatabaseWidget* dbWidget = m_dbTabWidget->currentDatabaseWidget()) {
if (Database* db = dbWidget->database()) {
return db->metadata()->customData();
}
}
return m_customData;
}

void BrowserOptionDialog::loadSettings()
{
BrowserSettings settings;
Expand Down Expand Up @@ -88,6 +108,9 @@ void BrowserOptionDialog::loadSettings()
m_ui->firefoxSupport->setChecked(settings.firefoxSupport());
m_ui->vivaldiSupport->setChecked(settings.vivaldiSupport());

// Update the stored key list every time settings are loaded
updateModel();

#if defined(KEEPASSXC_DIST_APPIMAGE)
m_ui->supportBrowserProxy->setChecked(true);
m_ui->supportBrowserProxy->setEnabled(false);
Expand Down Expand Up @@ -139,3 +162,42 @@ void BrowserOptionDialog::showProxyLocationFileDialog()
fileTypeFilter);
m_ui->customProxyLocation->setText(proxyLocation);
}

void BrowserOptionDialog::removeSelectedKey()
{
if (QMessageBox::Yes != MessageBox::question(this,
tr("Delete the selected key?"),
tr("Do you really want to delete the selected key?\n"
"This may cause the affected plugins to malfunction."),
QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel)) {
return;
}

const QItemSelectionModel* itemSelectionModel = m_ui->customDataTable->selectionModel();
if (itemSelectionModel) {
for (const QModelIndex& index : itemSelectionModel->selectedRows(0)) {
const QString key = index.data().toString();
customData()->remove(key);
}
updateModel();
}
}

void BrowserOptionDialog::toggleRemoveButton(const QItemSelection& selected)
{
m_ui->removeCustomDataButton->setEnabled(!selected.isEmpty());
}

void BrowserOptionDialog::updateModel()
{
m_customDataModel->clear();
m_customDataModel->setHorizontalHeaderLabels({tr("Key"), tr("Value")});

for (const QString& key : customData()->keys()) {
m_customDataModel->appendRow(QList<QStandardItem*>()
<< new QStandardItem(key)
<< new QStandardItem(customData()->value(key)));
}

m_ui->removeCustomDataButton->setEnabled(false);
}
16 changes: 15 additions & 1 deletion src/browser/BrowserOptionDialog.h
Expand Up @@ -22,6 +22,11 @@

#include <QWidget>
#include <QScopedPointer>
#include <QStandardItemModel>
#include <QItemSelection>
#include <QPointer>
#include "core/CustomData.h"
#include "gui/DatabaseTabWidget.h"

namespace Ui {
class BrowserOptionDialog;
Expand All @@ -32,9 +37,11 @@ class BrowserOptionDialog : public QWidget
Q_OBJECT

public:
explicit BrowserOptionDialog(QWidget* parent = nullptr);
explicit BrowserOptionDialog(DatabaseTabWidget* parent = nullptr);
~BrowserOptionDialog();

CustomData* customData() const;

public slots:
void loadSettings();
void saveSettings();
Expand All @@ -45,9 +52,16 @@ public slots:

private slots:
void showProxyLocationFileDialog();
void removeSelectedKey();
void toggleRemoveButton(const QItemSelection& selected);

private:
void updateModel();
QScopedPointer<Ui::BrowserOptionDialog> m_ui;

QPointer<CustomData> m_customData;
QPointer<QStandardItemModel> m_customDataModel;
DatabaseTabWidget* const m_dbTabWidget;
};

#endif // BROWSEROPTIONDIALOG_H
52 changes: 52 additions & 0 deletions src/browser/BrowserOptionDialog.ui
Expand Up @@ -230,6 +230,58 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Stored Keys</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTableView" name="customDataTable">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>200</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="removeCustomDataButton">
<property name="text">
<string>Remove</string>
</property>
</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>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
Expand Down
38 changes: 18 additions & 20 deletions src/browser/BrowserService.cpp
Expand Up @@ -107,12 +107,12 @@ QString BrowserService::getDatabaseRootUuid()
{
Database* db = getDatabase();
if (!db) {
return QString();
return {};
}

Group* rootGroup = db->rootGroup();
if (!rootGroup) {
return QString();
return {};
}

return rootGroup->uuid().toHex();
Expand All @@ -122,12 +122,12 @@ QString BrowserService::getDatabaseRecycleBinUuid()
{
Database* db = getDatabase();
if (!db) {
return QString();
return {};
}

Group* recycleBin = db->metadata()->recycleBin();
if (!recycleBin) {
return QString();
return {};
}
return recycleBin->uuid().toHex();
}
Expand Down Expand Up @@ -173,8 +173,8 @@ QString BrowserService::storeKey(const QString& key)
return id;
}

Entry* config = getConfigEntry(true);
if (!config) {
Database* db = getDatabase();
if (!db) {
return {};
}

Expand All @@ -200,7 +200,7 @@ QString BrowserService::storeKey(const QString& key)
return {};
}

contains = config->attributes()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
contains = db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
if (contains) {
dialogResult = QMessageBox::warning(nullptr, tr("KeePassXC: Overwrite existing key?"),
tr("A shared encryption key with the name \"%1\" "
Expand All @@ -210,18 +210,18 @@ QString BrowserService::storeKey(const QString& key)
}
} while (contains && dialogResult == QMessageBox::No);

config->attributes()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + id, key, true);
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + id, key);
return id;
}

QString BrowserService::getKey(const QString& id)
{
Entry* config = getConfigEntry();
if (!config) {
return QString();
Database* db = getDatabase();
if (!db) {
return {};
}

return config->attributes()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
return db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
}

QJsonArray BrowserService::findMatchingEntries(const QString& id, const QString& url, const QString& submitUrl, const QString& realm)
Expand Down Expand Up @@ -420,16 +420,16 @@ void BrowserService::removeSharedEncryptionKeys()
return;
}

Entry* entry = getConfigEntry();
if (!entry) {
Database* db = getDatabase();
if (!db) {
QMessageBox::information(0, tr("KeePassXC: Settings not available!"),
tr("The active database does not contain a settings entry."),
QMessageBox::Ok);
return;
}

QStringList keysToRemove;
for (const QString& key : entry->attributes()->keys()) {
for (const QString& key : db->metadata()->customData()->keys()) {
if (key.startsWith(ASSOCIATE_KEY_PREFIX)) {
keysToRemove << key;
}
Expand All @@ -442,11 +442,9 @@ void BrowserService::removeSharedEncryptionKeys()
return;
}

entry->beginUpdate();
for (const QString& key : keysToRemove) {
entry->attributes()->remove(key);
db->metadata()->customData()->remove(key);
}
entry->endUpdate();

const int count = keysToRemove.count();
QMessageBox::information(0, tr("KeePassXC: Removed keys from database"),
Expand Down Expand Up @@ -481,9 +479,9 @@ void BrowserService::removeStoredPermissions()
return;
}

if (entry->attributes()->contains(KEEPASSXCBROWSER_NAME)) {
if (entry->customData()->contains(KEEPASSXCBROWSER_NAME)) {
entry->beginUpdate();
entry->attributes()->remove(KEEPASSXCBROWSER_NAME);
entry->customData()->remove(KEEPASSXCBROWSER_NAME);
entry->endUpdate();
++counter;
}
Expand Down
15 changes: 9 additions & 6 deletions src/gui/MainWindow.cpp
Expand Up @@ -116,7 +116,9 @@ class HttpPlugin: public ISettingsPage
class BrowserPlugin: public ISettingsPage
{
public:
BrowserPlugin(DatabaseTabWidget* tabWidget) {
BrowserPlugin(DatabaseTabWidget* tabWidget) :
m_dbTabWidget(tabWidget)
{
m_nativeMessagingHost = QSharedPointer<NativeMessagingHost>(new NativeMessagingHost(tabWidget));
}

Expand All @@ -135,7 +137,7 @@ class BrowserPlugin: public ISettingsPage
}

QWidget* createWidget() override {
BrowserOptionDialog* dlg = new BrowserOptionDialog();
BrowserOptionDialog* dlg = new BrowserOptionDialog(m_dbTabWidget);
QObject::connect(dlg, SIGNAL(removeSharedEncryptionKeys()), m_nativeMessagingHost.data(), SLOT(removeSharedEncryptionKeys()));
QObject::connect(dlg, SIGNAL(removeStoredPermissions()), m_nativeMessagingHost.data(), SLOT(removeStoredPermissions()));
return dlg;
Expand All @@ -156,7 +158,8 @@ class BrowserPlugin: public ISettingsPage
}
}
private:
QSharedPointer<NativeMessagingHost> m_nativeMessagingHost;
QSharedPointer<NativeMessagingHost> m_nativeMessagingHost;
DatabaseTabWidget* const m_dbTabWidget;
};
#endif

Expand All @@ -169,7 +172,7 @@ MainWindow::MainWindow()
, m_appExiting(false)
{
m_ui->setupUi(this);

#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) && !defined(QT_NO_DBUS)
new MainWindowAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
Expand Down Expand Up @@ -891,7 +894,7 @@ void MainWindow::updateTrayIcon()
connect(actionToggle, SIGNAL(triggered()), SLOT(toggleWindow()));

m_trayIcon->setContextMenu(menu);

m_trayIcon->setIcon(filePath()->applicationIcon());
m_trayIcon->show();
}
Expand Down Expand Up @@ -1150,4 +1153,4 @@ void MainWindow::closeAllDatabases()
void MainWindow::lockAllDatabases()
{
lockDatabasesAfterInactivity();
}
}

0 comments on commit 60d8670

Please sign in to comment.