FdoSecrets: skip entries in recycle bin when searching (fix #7933)

This commit is contained in:
Aetf 2022-05-06 17:47:34 -04:00 committed by Jonathan White
parent 121d54c96a
commit 107dcae26c
5 changed files with 49 additions and 10 deletions

View file

@ -276,7 +276,12 @@ namespace FdoSecrets
EntrySearcher(caseSensitive, skipProtected).search(terms, m_exposedGroup, forceSearch); EntrySearcher(caseSensitive, skipProtected).search(terms, m_exposedGroup, forceSearch);
items.reserve(foundEntries.size()); items.reserve(foundEntries.size());
for (const auto& entry : foundEntries) { for (const auto& entry : foundEntries) {
items << m_entryToItem.value(entry); const auto item = m_entryToItem.value(entry);
// it's possible that we don't have a corresponding item for the entry
// this can happen when the recycle bin is below the exposed group.
if (item) {
items << item;
}
} }
return {}; return {};
} }
@ -458,7 +463,7 @@ namespace FdoSecrets
}); });
// Another possibility is the group being moved to recycle bin. // Another possibility is the group being moved to recycle bin.
connect(m_exposedGroup.data(), &Group::modified, this, [this]() { connect(m_exposedGroup.data(), &Group::modified, this, [this]() {
if (inRecycleBin(m_exposedGroup->parentGroup())) { if (inRecycleBin(m_exposedGroup)) {
// reset the exposed group to none // reset the exposed group to none
FdoSecrets::settings()->setExposedGroup(m_backend->database().data(), {}); FdoSecrets::settings()->setExposedGroup(m_backend->database().data(), {});
} }
@ -677,11 +682,7 @@ namespace FdoSecrets
bool Collection::inRecycleBin(Group* group) const bool Collection::inRecycleBin(Group* group) const
{ {
Q_ASSERT(m_backend); Q_ASSERT(m_backend);
Q_ASSERT(group);
if (!group) {
// the root group's parent is nullptr, we treat it as not in recycle bin.
return false;
}
if (!m_backend->database()->metadata()) { if (!m_backend->database()->metadata()) {
return false; return false;

View file

@ -107,6 +107,9 @@ namespace FdoSecrets
DatabaseWidget* backend() const; DatabaseWidget* backend() const;
QString backendFilePath() const; QString backendFilePath() const;
Service* service() const; Service* service() const;
/**
* similar to Group::isRecycled, but we also return true when the group itself is the recycle bin
*/
bool inRecycleBin(Group* group) const; bool inRecycleBin(Group* group) const;
bool inRecycleBin(Entry* entry) const; bool inRecycleBin(Entry* entry) const;

View file

@ -258,12 +258,13 @@ namespace FdoSecrets
} }
// item locked state already covers its collection's locked state // item locked state already covers its collection's locked state
for (const auto& item : asConst(items)) { for (const auto& item : asConst(items)) {
bool l; Q_ASSERT(item);
ret = item->locked(client, l); bool itemLocked;
ret = item->locked(client, itemLocked);
if (ret.err()) { if (ret.err()) {
return ret; return ret;
} }
if (l) { if (itemLocked) {
locked.append(item); locked.append(item);
} else { } else {
unlocked.append(item); unlocked.append(item);

View file

@ -1564,6 +1564,39 @@ void TestGuiFdoSecrets::testModifyingExposedGroup()
} }
} }
void TestGuiFdoSecrets::testNoExposeRecycleBin()
{
// when the recycle bin is underneath the exposed group
// be careful not to expose entries in there
FdoSecrets::settings()->setExposedGroup(m_db, m_db->rootGroup()->uuid());
m_db->metadata()->setRecycleBinEnabled(true);
auto entry = m_db->rootGroup()->entries().first();
VERIFY(entry);
m_db->recycleEntry(entry);
processEvents();
auto service = enableService();
VERIFY(service);
auto coll = getDefaultCollection(service);
VERIFY(coll);
// exposing subgroup does not expose entries in other groups
DBUS_GET(itemPaths, coll->items());
QSet<Entry*> exposedEntries;
for (const auto& itemPath : itemPaths) {
exposedEntries << m_plugin->dbus()->pathToObject<Item>(itemPath)->backend();
}
VERIFY(!exposedEntries.contains(entry));
// searching should not return the entry
DBUS_GET2(unlocked, locked, service->SearchItems({{"Title", entry->title()}}));
COMPARE(locked, {});
COMPARE(unlocked, {});
}
void TestGuiFdoSecrets::lockDatabaseInBackend() void TestGuiFdoSecrets::lockDatabaseInBackend()
{ {
m_dbWidget->lock(); m_dbWidget->lock();

View file

@ -97,6 +97,7 @@ private slots:
void testExposeSubgroup(); void testExposeSubgroup();
void testModifyingExposedGroup(); void testModifyingExposedGroup();
void testNoExposeRecycleBin();
void testHiddenFilename(); void testHiddenFilename();
void testDuplicateName(); void testDuplicateName();