From 6a35bbea2f34f4b81d50a3e9e554445dc74f62e7 Mon Sep 17 00:00:00 2001 From: piegames Date: Wed, 20 May 2020 14:53:42 +0200 Subject: [PATCH] Add browser service search for entries via UUID --- src/browser/BrowserService.cpp | 15 ++++++++-- src/browser/BrowserService.h | 1 + tests/TestBrowser.cpp | 50 ++++++++++++++++++++++++++++++++++ tests/TestBrowser.h | 1 + 4 files changed, 65 insertions(+), 2 deletions(-) diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index eb752996c..f46472b9c 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -597,7 +597,7 @@ BrowserService::searchEntries(const QSharedPointer& db, const QString& } } - if (!handleURL(entry->url(), url, submitUrl)) { + if (!handleEntry(entry, url, submitUrl)) { continue; } @@ -1004,6 +1004,17 @@ bool BrowserService::removeFirstDomain(QString& hostname) return false; } +/* Test if a search URL matches a custom entry. If the URL has the schema "keepassxc", some special checks will be made. + * Otherwise, this simply delegates to handleURL(). */ +bool BrowserService::handleEntry(Entry* entry, const QString& url, const QString& submitUrl) +{ + // Use this special scheme to find entries by UUID + if (url.startsWith("keepassxc://")) { + return ("keepassxc://by-uuid/" + entry->uuidToHex()) == url; + } + return handleURL(entry->url(), url, submitUrl); +} + bool BrowserService::handleURL(const QString& entryUrl, const QString& url, const QString& submitUrl) { if (entryUrl.isEmpty()) { @@ -1022,7 +1033,7 @@ bool BrowserService::handleURL(const QString& entryUrl, const QString& url, cons } // Make a direct compare if a local file is used - if (url.contains("file://")) { + if (url.startsWith("file://")) { return entryUrl == submitUrl; } diff --git a/src/browser/BrowserService.h b/src/browser/BrowserService.h index f52b502b3..8c8e3460f 100644 --- a/src/browser/BrowserService.h +++ b/src/browser/BrowserService.h @@ -139,6 +139,7 @@ private: const QString& fullUrl) const; bool schemeFound(const QString& url); bool removeFirstDomain(QString& hostname); + bool handleEntry(Entry* entry, const QString& url, const QString& submitUrl); bool handleURL(const QString& entryUrl, const QString& url, const QString& submitUrl); QString baseDomain(const QString& hostname) const; QSharedPointer getDatabase(); diff --git a/tests/TestBrowser.cpp b/tests/TestBrowser.cpp index 3e518c1e2..1255da4cf 100644 --- a/tests/TestBrowser.cpp +++ b/tests/TestBrowser.cpp @@ -223,6 +223,55 @@ void TestBrowser::testSearchEntries() QCOMPARE(result[3]->url(), QString("github.com/login")); } +void TestBrowser::testSearchEntriesByUUID() +{ + auto db = QSharedPointer::create(); + auto* root = db->rootGroup(); + + /* The URLs don't really matter for this test, we just need some entries */ + QStringList urls = {"https://github.com/login_page", + "https://github.com/login", + "https://github.com/", + "github.com/login", + "http://github.com", + "http://github.com/login", + "github.com", + "github.com/login", + "https://github", + "github.com", + "", + "not an URL"}; + auto entries = createEntries(urls, root); + + for (Entry* entry : entries) { + QString testUrl = "keepassxc://by-uuid/" + entry->uuidToHex(); + /* Look for an entry with that UUID. First using handleEntry, then through the search */ + QCOMPARE(m_browserService->handleEntry(entry, testUrl, ""), true); + auto result = m_browserService->searchEntries(db, testUrl, ""); + QCOMPARE(result.length(), 1); + QCOMPARE(result[0], entry); + } + + /* Test for entries that don't exist */ + QStringList uuids = {"00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002/", + "invalid uuid", + "000000000000000000000000000000000000000" + "00000000000000000000000"}; + + for (QString uuid : uuids) { + QString testUrl = "keepassxc://by-uuid/" + uuid; + + for (Entry* entry : entries) { + QCOMPARE(m_browserService->handleEntry(entry, testUrl, ""), false); + } + + auto result = m_browserService->searchEntries(db, testUrl, ""); + QCOMPARE(result.length(), 0); + } +} + void TestBrowser::testSearchEntriesWithPort() { auto db = QSharedPointer::create(); @@ -419,6 +468,7 @@ QList TestBrowser::createEntries(QStringList& urls, Group* root) const entry->beginUpdate(); entry->setUrl(urls[i]); entry->setUsername(QString("User %1").arg(i)); + entry->setUuid(QUuid::createUuid()); entry->endUpdate(); entries.push_back(entry); } diff --git a/tests/TestBrowser.h b/tests/TestBrowser.h index c8be3d6ca..37daffe74 100644 --- a/tests/TestBrowser.h +++ b/tests/TestBrowser.h @@ -41,6 +41,7 @@ private slots: void testBaseDomain(); void testSortPriority(); void testSearchEntries(); + void testSearchEntriesByUUID(); void testSearchEntriesWithPort(); void testSearchEntriesWithAdditionalURLs(); void testInvalidEntries();