mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-23 13:35:21 -04:00
FdoSecrets: skip entries in recycle bin when searching (fix #7933)
This commit is contained in:
parent
121d54c96a
commit
107dcae26c
5 changed files with 49 additions and 10 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -97,6 +97,7 @@ private slots:
|
||||||
|
|
||||||
void testExposeSubgroup();
|
void testExposeSubgroup();
|
||||||
void testModifyingExposedGroup();
|
void testModifyingExposedGroup();
|
||||||
|
void testNoExposeRecycleBin();
|
||||||
|
|
||||||
void testHiddenFilename();
|
void testHiddenFilename();
|
||||||
void testDuplicateName();
|
void testDuplicateName();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue