From 0da9efdbd4efc1e8b15000785ca02c4b8803d078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20V=C3=A4nttinen?= Date: Mon, 21 Jan 2019 21:24:57 +0200 Subject: [PATCH] Fix updating reference passwords from KeePassXC-Browser (#2218) * Allow updating reference passwords * Fix function change after refactor --- src/browser/BrowserService.cpp | 15 ++++++++++++++- src/core/EntryAttributes.cpp | 18 ++++++++++++++++++ src/core/EntryAttributes.h | 2 ++ tests/TestEntry.cpp | 1 + 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index 834d76aca..a1ea5d684 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -371,6 +371,17 @@ void BrowserService::updateEntry(const QString& id, return; } + // Check if the entry password is a reference. If so, update the original entry instead + while (entry->attributes()->isReference(EntryAttributes::PasswordKey)) { + const QUuid referenceUuid = entry->attributes()->referenceUuid(EntryAttributes::PasswordKey); + if (!referenceUuid.isNull()) { + entry = db->rootGroup()->findEntryByUuid(referenceUuid); + if (!entry) { + return; + } + } + } + QString username = entry->username(); if (username.isEmpty()) { return; @@ -391,7 +402,9 @@ void BrowserService::updateEntry(const QString& id, if (browserSettings()->alwaysAllowUpdate() || dialogResult == MessageBox::Save) { entry->beginUpdate(); - entry->setUsername(login); + if (!entry->attributes()->isReference(EntryAttributes::UserNameKey)) { + entry->setUsername(login); + } entry->setPassword(password); entry->endUpdate(); } diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp index fc0793ce8..5c836e1e8 100644 --- a/src/core/EntryAttributes.cpp +++ b/src/core/EntryAttributes.cpp @@ -244,6 +244,24 @@ void EntryAttributes::copyDataFrom(const EntryAttributes* other) } } +QUuid EntryAttributes::referenceUuid(const QString& key) const +{ + if (!m_attributes.contains(key)) { + Q_ASSERT(false); + return {}; + } + + auto match = matchReference(value(key)); + if (match.hasMatch()) { + const QString uuid = match.captured("SearchText"); + if (!uuid.isEmpty()) { + return QUuid::fromRfc4122(QByteArray::fromHex(uuid.toLatin1())); + } + } + + return {}; +} + bool EntryAttributes::operator==(const EntryAttributes& other) const { return (m_attributes == other.m_attributes && m_protectedAttributes == other.m_protectedAttributes); diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h index 15c84bdcd..fdae8a624 100644 --- a/src/core/EntryAttributes.h +++ b/src/core/EntryAttributes.h @@ -24,6 +24,7 @@ #include #include #include +#include class EntryAttributes : public QObject { @@ -47,6 +48,7 @@ public: void clear(); int attributesSize() const; void copyDataFrom(const EntryAttributes* other); + QUuid referenceUuid(const QString& key) const; bool operator==(const EntryAttributes& other) const; bool operator!=(const EntryAttributes& other) const; diff --git a/tests/TestEntry.cpp b/tests/TestEntry.cpp index 23af41e6a..c174e798d 100644 --- a/tests/TestEntry.cpp +++ b/tests/TestEntry.cpp @@ -140,6 +140,7 @@ void TestEntry::testClone() QCOMPARE(entryClonePassRef->timeInfo().creationTime(), entryOrgClone->timeInfo().creationTime()); QVERIFY(entryClonePassRef->attributes()->isReference(EntryAttributes::PasswordKey)); QCOMPARE(entryClonePassRef->resolvePlaceholder(entryCloneUserRef->password()), entryOrg->password()); + QCOMPARE(entryClonePassRef->attributes()->referenceUuid(EntryAttributes::PasswordKey), entryOrgClone->uuid()); } void TestEntry::testResolveUrl()