FdoSecrets: use EntrySearcher's internal search API

This commit is contained in:
Aetf 2019-11-01 16:42:00 -04:00 committed by Jonathan White
parent b96c1e92a3
commit f9097c84e9
6 changed files with 54 additions and 37 deletions

View File

@ -24,7 +24,7 @@
#include "core/Config.h"
#include "core/Database.h"
#include "core/EntrySearcher.h"
#include "core/Tools.h"
#include "gui/DatabaseTabWidget.h"
#include "gui/DatabaseWidget.h"
@ -233,24 +233,16 @@ namespace FdoSecrets
}
}
static QMap<QString, QString> attrKeyToField{
{EntryAttributes::TitleKey, QStringLiteral("title")},
{EntryAttributes::UserNameKey, QStringLiteral("user")},
{EntryAttributes::URLKey, QStringLiteral("url")},
{EntryAttributes::NotesKey, QStringLiteral("notes")},
};
QStringList terms;
QList<EntrySearcher::SearchTerm> terms;
for (auto it = attributes.constBegin(); it != attributes.constEnd(); ++it) {
if (it.key() == EntryAttributes::PasswordKey) {
continue;
}
auto field = attrKeyToField.value(it.key(), QStringLiteral("_") + Item::encodeAttributeKey(it.key()));
terms << QStringLiteral(R"raw(+%1:"%2")raw").arg(field, it.value());
terms << attributeToTerm(it.key(), it.value());
}
QList<Item*> items;
const auto foundEntries = EntrySearcher().search(terms.join(' '), m_exposedGroup);
const auto foundEntries = EntrySearcher().search(terms, m_exposedGroup);
items.reserve(foundEntries.size());
for (const auto& entry : foundEntries) {
items << m_entryToItem.value(entry);
@ -258,6 +250,28 @@ namespace FdoSecrets
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*>
Collection::createItem(const QVariantMap& properties, const SecretStruct& secret, bool replace, PromptBase*& prompt)
{

View File

@ -21,6 +21,7 @@
#include "DBusObject.h"
#include "adaptors/CollectionAdaptor.h"
#include "core/EntrySearcher.h"
#include <QPointer>
#include <QSet>
@ -90,6 +91,8 @@ namespace FdoSecrets
bool inRecycleBin(Group* group) const;
bool inRecycleBin(Entry* entry) const;
static EntrySearcher::SearchTerm attributeToTerm(const QString& key, const QString& value);
public slots:
// expose some methods for Prmopt to use
void doLock();

View File

@ -99,10 +99,7 @@ namespace FdoSecrets
// add custom attributes
const auto customKeys = entryAttrs->customKeys();
for (const auto& attr : customKeys) {
// decode attr key
auto decoded = decodeAttributeKey(attr);
attrs[decoded] = entryAttrs->value(attr);
attrs[attr] = entryAttrs->value(attr);
}
// add some informative and readonly attributes
@ -134,8 +131,7 @@ namespace FdoSecrets
continue;
}
auto encoded = encodeAttributeKey(it.key());
entryAttrs->set(encoded, it.value());
entryAttrs->set(it.key(), it.value());
}
m_backend->endUpdate();
@ -354,16 +350,6 @@ namespace FdoSecrets
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)
{
auto mimeName = contentType.split(';').takeFirst().trimmed();

View File

@ -67,15 +67,6 @@ namespace FdoSecrets
public:
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);
Entry* backend() const;

View File

@ -19,8 +19,11 @@
#include "TestGlobal.h"
#include "core/EntrySearcher.h"
#include "fdosecrets/GcryptMPI.h"
#include "fdosecrets/objects/SessionCipher.h"
#include "fdosecrets/objects/Collection.h"
#include "fdosecrets/objects/Item.h"
#include "crypto/Crypto.h"
@ -90,3 +93,22 @@ void TestFdoSecrets::testDhIetf1024Sha256Aes128CbcPkcs7()
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);
}

View File

@ -30,6 +30,7 @@ private slots:
void testGcryptMPI();
void testDhIetf1024Sha256Aes128CbcPkcs7();
void testCrazyAttributeKey();
};
#endif // KEEPASSXC_TESTFDOSECRETS_H