mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-08-14 17:26:27 -04:00
FdoSecrets: use EntrySearcher's internal search API
This commit is contained in:
parent
b96c1e92a3
commit
f9097c84e9
6 changed files with 54 additions and 37 deletions
|
@ -24,7 +24,7 @@
|
||||||
|
|
||||||
#include "core/Config.h"
|
#include "core/Config.h"
|
||||||
#include "core/Database.h"
|
#include "core/Database.h"
|
||||||
#include "core/EntrySearcher.h"
|
#include "core/Tools.h"
|
||||||
#include "gui/DatabaseTabWidget.h"
|
#include "gui/DatabaseTabWidget.h"
|
||||||
#include "gui/DatabaseWidget.h"
|
#include "gui/DatabaseWidget.h"
|
||||||
|
|
||||||
|
@ -233,24 +233,16 @@ namespace FdoSecrets
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static QMap<QString, QString> attrKeyToField{
|
QList<EntrySearcher::SearchTerm> terms;
|
||||||
{EntryAttributes::TitleKey, QStringLiteral("title")},
|
|
||||||
{EntryAttributes::UserNameKey, QStringLiteral("user")},
|
|
||||||
{EntryAttributes::URLKey, QStringLiteral("url")},
|
|
||||||
{EntryAttributes::NotesKey, QStringLiteral("notes")},
|
|
||||||
};
|
|
||||||
|
|
||||||
QStringList terms;
|
|
||||||
for (auto it = attributes.constBegin(); it != attributes.constEnd(); ++it) {
|
for (auto it = attributes.constBegin(); it != attributes.constEnd(); ++it) {
|
||||||
if (it.key() == EntryAttributes::PasswordKey) {
|
if (it.key() == EntryAttributes::PasswordKey) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto field = attrKeyToField.value(it.key(), QStringLiteral("_") + Item::encodeAttributeKey(it.key()));
|
terms << attributeToTerm(it.key(), it.value());
|
||||||
terms << QStringLiteral(R"raw(+%1:"%2")raw").arg(field, it.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Item*> items;
|
QList<Item*> items;
|
||||||
const auto foundEntries = EntrySearcher().search(terms.join(' '), m_exposedGroup);
|
const auto foundEntries = EntrySearcher().search(terms, m_exposedGroup);
|
||||||
items.reserve(foundEntries.size());
|
items.reserve(foundEntries.size());
|
||||||
for (const auto& entry : foundEntries) {
|
for (const auto& entry : foundEntries) {
|
||||||
items << m_entryToItem.value(entry);
|
items << m_entryToItem.value(entry);
|
||||||
|
@ -258,6 +250,28 @@ namespace FdoSecrets
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntrySearcher::SearchTerm Collection::attributeToTerm(const QString& key, const QString& value)
|
||||||
|
{
|
||||||
|
static QMap<QString, EntrySearcher::Field> attrKeyToField{
|
||||||
|
{EntryAttributes::TitleKey, EntrySearcher::Field::Title},
|
||||||
|
{EntryAttributes::UserNameKey, EntrySearcher::Field::Username},
|
||||||
|
{EntryAttributes::URLKey, EntrySearcher::Field::Url},
|
||||||
|
{EntryAttributes::NotesKey, EntrySearcher::Field::Notes},
|
||||||
|
};
|
||||||
|
|
||||||
|
EntrySearcher::SearchTerm term{};
|
||||||
|
term.field = attrKeyToField.value(key, EntrySearcher::Field::AttributeValue);
|
||||||
|
term.word = key;
|
||||||
|
term.exclude = false;
|
||||||
|
|
||||||
|
const auto useWildcards = false;
|
||||||
|
const auto exactMatch = true;
|
||||||
|
const auto caseSensitive = true;
|
||||||
|
term.regex = Tools::convertToRegex(value, useWildcards, exactMatch, caseSensitive);
|
||||||
|
|
||||||
|
return term;
|
||||||
|
}
|
||||||
|
|
||||||
DBusReturn<Item*>
|
DBusReturn<Item*>
|
||||||
Collection::createItem(const QVariantMap& properties, const SecretStruct& secret, bool replace, PromptBase*& prompt)
|
Collection::createItem(const QVariantMap& properties, const SecretStruct& secret, bool replace, PromptBase*& prompt)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "DBusObject.h"
|
#include "DBusObject.h"
|
||||||
|
|
||||||
#include "adaptors/CollectionAdaptor.h"
|
#include "adaptors/CollectionAdaptor.h"
|
||||||
|
#include "core/EntrySearcher.h"
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
|
@ -90,6 +91,8 @@ namespace FdoSecrets
|
||||||
bool inRecycleBin(Group* group) const;
|
bool inRecycleBin(Group* group) const;
|
||||||
bool inRecycleBin(Entry* entry) const;
|
bool inRecycleBin(Entry* entry) const;
|
||||||
|
|
||||||
|
static EntrySearcher::SearchTerm attributeToTerm(const QString& key, const QString& value);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
// expose some methods for Prmopt to use
|
// expose some methods for Prmopt to use
|
||||||
void doLock();
|
void doLock();
|
||||||
|
|
|
@ -99,10 +99,7 @@ namespace FdoSecrets
|
||||||
// add custom attributes
|
// add custom attributes
|
||||||
const auto customKeys = entryAttrs->customKeys();
|
const auto customKeys = entryAttrs->customKeys();
|
||||||
for (const auto& attr : customKeys) {
|
for (const auto& attr : customKeys) {
|
||||||
// decode attr key
|
attrs[attr] = entryAttrs->value(attr);
|
||||||
auto decoded = decodeAttributeKey(attr);
|
|
||||||
|
|
||||||
attrs[decoded] = entryAttrs->value(attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add some informative and readonly attributes
|
// add some informative and readonly attributes
|
||||||
|
@ -134,8 +131,7 @@ namespace FdoSecrets
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto encoded = encodeAttributeKey(it.key());
|
entryAttrs->set(it.key(), it.value());
|
||||||
entryAttrs->set(encoded, it.value());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_backend->endUpdate();
|
m_backend->endUpdate();
|
||||||
|
@ -354,16 +350,6 @@ namespace FdoSecrets
|
||||||
return pathComponents.join('/');
|
return pathComponents.join('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Item::encodeAttributeKey(const QString& key)
|
|
||||||
{
|
|
||||||
return QUrl::toPercentEncoding(key, "", "_:").replace('%', '_');
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Item::decodeAttributeKey(const QString& key)
|
|
||||||
{
|
|
||||||
return QString::fromUtf8(QByteArray::fromPercentEncoding(key.toLatin1(), '_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEntrySecret(Entry* entry, const QByteArray& data, const QString& contentType)
|
void setEntrySecret(Entry* entry, const QByteArray& data, const QString& contentType)
|
||||||
{
|
{
|
||||||
auto mimeName = contentType.split(';').takeFirst().trimmed();
|
auto mimeName = contentType.split(';').takeFirst().trimmed();
|
||||||
|
|
|
@ -67,15 +67,6 @@ namespace FdoSecrets
|
||||||
public:
|
public:
|
||||||
static const QSet<QString> ReadOnlyAttributes;
|
static const QSet<QString> ReadOnlyAttributes;
|
||||||
|
|
||||||
/**
|
|
||||||
* Due to the limitation in EntrySearcher, custom attr key cannot contain ':',
|
|
||||||
* Thus we encode the key when saving and decode it when returning.
|
|
||||||
* @param key
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static QString encodeAttributeKey(const QString& key);
|
|
||||||
static QString decodeAttributeKey(const QString& key);
|
|
||||||
|
|
||||||
DBusReturn<void> setProperties(const QVariantMap& properties);
|
DBusReturn<void> setProperties(const QVariantMap& properties);
|
||||||
|
|
||||||
Entry* backend() const;
|
Entry* backend() const;
|
||||||
|
|
|
@ -19,8 +19,11 @@
|
||||||
|
|
||||||
#include "TestGlobal.h"
|
#include "TestGlobal.h"
|
||||||
|
|
||||||
|
#include "core/EntrySearcher.h"
|
||||||
#include "fdosecrets/GcryptMPI.h"
|
#include "fdosecrets/GcryptMPI.h"
|
||||||
#include "fdosecrets/objects/SessionCipher.h"
|
#include "fdosecrets/objects/SessionCipher.h"
|
||||||
|
#include "fdosecrets/objects/Collection.h"
|
||||||
|
#include "fdosecrets/objects/Item.h"
|
||||||
|
|
||||||
#include "crypto/Crypto.h"
|
#include "crypto/Crypto.h"
|
||||||
|
|
||||||
|
@ -90,3 +93,22 @@ void TestFdoSecrets::testDhIetf1024Sha256Aes128CbcPkcs7()
|
||||||
|
|
||||||
QCOMPARE(cipher->m_aesKey.toHex(), QByteArrayLiteral("6b8f5ee55138eac37118508be21e7834"));
|
QCOMPARE(cipher->m_aesKey.toHex(), QByteArrayLiteral("6b8f5ee55138eac37118508be21e7834"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestFdoSecrets::testCrazyAttributeKey()
|
||||||
|
{
|
||||||
|
using FdoSecrets::Item;
|
||||||
|
using FdoSecrets::Collection;
|
||||||
|
|
||||||
|
const QScopedPointer<Group> root(new Group());
|
||||||
|
const QScopedPointer<Entry> e1(new Entry());
|
||||||
|
e1->setGroup(root.data());
|
||||||
|
|
||||||
|
const QString key = "_a:bc&-+'-e%12df_d";
|
||||||
|
const QString value = "value";
|
||||||
|
e1->attributes()->set(key, value);
|
||||||
|
|
||||||
|
// search for custom entries
|
||||||
|
const auto term = Collection::attributeToTerm(key, value);
|
||||||
|
const auto res = EntrySearcher().search({term}, root.data());
|
||||||
|
QCOMPARE(res.count(), 1);
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ private slots:
|
||||||
|
|
||||||
void testGcryptMPI();
|
void testGcryptMPI();
|
||||||
void testDhIetf1024Sha256Aes128CbcPkcs7();
|
void testDhIetf1024Sha256Aes128CbcPkcs7();
|
||||||
|
void testCrazyAttributeKey();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // KEEPASSXC_TESTFDOSECRETS_H
|
#endif // KEEPASSXC_TESTFDOSECRETS_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue