Implement KDBX 4.1 extended custom icons

This commit is contained in:
Janek Bevendorff
2021-11-10 02:29:36 +01:00
parent 70e62d90db
commit 390e14b2c6
17 changed files with 137 additions and 48 deletions

View File

@@ -28,7 +28,6 @@
#include "core/Tools.h"
#include "crypto/Crypto.h"
#include "format/KeePass2Writer.h"
#include "keys/PasswordKey.h"
#include "util/TemporaryFile.h"
QTEST_GUILESS_MAIN(TestDatabase)
@@ -214,3 +213,26 @@ void TestDatabase::testEmptyRecycleBinWithHierarchicalData()
writer.writeDatabase(&afterCleanup, db.data());
QVERIFY(afterCleanup.size() < initialSize);
}
void TestDatabase::testCustomIcons()
{
Database db;
QUuid uuid1 = QUuid::createUuid();
QByteArray icon1("icon 1");
Q_ASSERT(!icon1.isNull());
db.metadata()->addCustomIcon(uuid1, icon1);
Metadata::CustomIconData iconData = db.metadata()->customIcon(uuid1);
QCOMPARE(iconData.data, icon1);
QVERIFY(iconData.name.isNull());
QVERIFY(iconData.lastModified.isNull());
QUuid uuid2 = QUuid::createUuid();
QByteArray icon2("icon 2");
QDateTime date = QDateTime::currentDateTimeUtc();
db.metadata()->addCustomIcon(uuid2, icon2, "Test", date);
iconData = db.metadata()->customIcon(uuid2);
QCOMPARE(iconData.data, icon2);
QCOMPARE(iconData.name, QString("Test"));
QCOMPARE(iconData.lastModified, date);
}

View File

@@ -34,6 +34,7 @@ private slots:
void testEmptyRecycleBinOnNotCreated();
void testEmptyRecycleBinOnEmpty();
void testEmptyRecycleBinWithHierarchicalData();
void testCustomIcons();
};
#endif // KEEPASSX_TESTDATABASE_H

View File

@@ -152,3 +152,15 @@ void TestDeletedObjects::testDatabaseChange()
delete group;
}
void TestDeletedObjects::testCustomIconDeletion()
{
Database db;
QCOMPARE(db.deletedObjects().size(), 0);
QUuid uuid = QUuid::createUuid();
db.metadata()->addCustomIcon(uuid, QByteArray());
db.metadata()->removeCustomIcon(uuid);
QCOMPARE(db.deletedObjects().size(), 1);
QCOMPARE(db.deletedObjects().at(0).uuid, uuid);
}

View File

@@ -34,6 +34,7 @@ private slots:
void testDeletedObjectsFromFile();
void testDeletedObjectsFromNewDb();
void testDatabaseChange();
void testCustomIconDeletion();
};
#endif // KEEPASSX_TESTDELETEDOBJECTS_H

View File

@@ -316,33 +316,37 @@ void TestGroup::testCopyCustomIcon()
QUuid groupIconUuid = QUuid::createUuid();
QByteArray groupIcon("group icon");
dbSource->metadata()->addCustomIcon(groupIconUuid, groupIcon);
QString groupIconName("group icon");
dbSource->metadata()->addCustomIcon(groupIconUuid, groupIcon, groupIconName);
QUuid entryIconUuid = QUuid::createUuid();
QByteArray entryIcon("entry icon");
dbSource->metadata()->addCustomIcon(entryIconUuid, entryIcon);
QString entryIconName("entry icon");
dbSource->metadata()->addCustomIcon(entryIconUuid, entryIcon, entryIconName);
Group* group = new Group();
auto* group = new Group();
group->setParent(dbSource->rootGroup());
group->setIcon(groupIconUuid);
QCOMPARE(group->database()->metadata()->customIcon(groupIconUuid), groupIcon);
QCOMPARE(group->database()->metadata()->customIcon(groupIconUuid).data, groupIcon);
QCOMPARE(group->database()->metadata()->customIcon(groupIconUuid).name, groupIconName);
Entry* entry = new Entry();
auto* entry = new Entry();
entry->setGroup(dbSource->rootGroup());
entry->setIcon(entryIconUuid);
QCOMPARE(entry->database()->metadata()->customIcon(entryIconUuid), entryIcon);
QCOMPARE(entry->database()->metadata()->customIcon(entryIconUuid).data, entryIcon);
QCOMPARE(entry->database()->metadata()->customIcon(entryIconUuid).name, entryIconName);
QScopedPointer<Database> dbTarget(new Database());
group->setParent(dbTarget->rootGroup());
QVERIFY(dbTarget->metadata()->hasCustomIcon(groupIconUuid));
QCOMPARE(dbTarget->metadata()->customIcon(groupIconUuid), groupIcon);
QCOMPARE(group->database()->metadata()->customIcon(groupIconUuid), groupIcon);
QCOMPARE(dbTarget->metadata()->customIcon(groupIconUuid).data, groupIcon);
QCOMPARE(dbTarget->metadata()->customIcon(groupIconUuid).name, groupIconName);
entry->setGroup(dbTarget->rootGroup());
QVERIFY(dbTarget->metadata()->hasCustomIcon(entryIconUuid));
QCOMPARE(dbTarget->metadata()->customIcon(entryIconUuid), entryIcon);
QCOMPARE(entry->database()->metadata()->customIcon(entryIconUuid), entryIcon);
QCOMPARE(dbTarget->metadata()->customIcon(entryIconUuid).data, entryIcon);
QCOMPARE(dbTarget->metadata()->customIcon(entryIconUuid).name, entryIconName);
}
void TestGroup::testClone()
@@ -423,37 +427,36 @@ void TestGroup::testCopyCustomIcons()
QScopedPointer<Database> dbSource(new Database());
QScopedPointer<Database> dbTarget(new Database());
QByteArray iconImage1("icon 1");
QByteArray iconImage2("icon 2");
Metadata::CustomIconData icon1 = {QByteArray("icon 1"), "icon 1", Clock::currentDateTimeUtc()};
Metadata::CustomIconData icon2 = {QByteArray("icon 2"), "icon 2", Clock::currentDateTimeUtc()};
QScopedPointer<Group> group1(new Group());
group1->setParent(dbSource->rootGroup());
QUuid group1Icon = QUuid::createUuid();
dbSource->metadata()->addCustomIcon(group1Icon, iconImage1);
dbSource->metadata()->addCustomIcon(group1Icon, icon1);
group1->setIcon(group1Icon);
QScopedPointer<Group> group2(new Group());
group2->setParent(group1.data());
QUuid group2Icon = QUuid::createUuid();
dbSource->metadata()->addCustomIcon(group2Icon, iconImage1);
dbSource->metadata()->addCustomIcon(group2Icon, icon1);
group2->setIcon(group2Icon);
QScopedPointer<Entry> entry1(new Entry());
entry1->setGroup(group2.data());
QUuid entry1IconOld = QUuid::createUuid();
dbSource->metadata()->addCustomIcon(entry1IconOld, iconImage1);
dbSource->metadata()->addCustomIcon(entry1IconOld, icon1);
entry1->setIcon(entry1IconOld);
// add history item
entry1->beginUpdate();
QUuid entry1IconNew = QUuid::createUuid();
dbSource->metadata()->addCustomIcon(entry1IconNew, iconImage1);
dbSource->metadata()->addCustomIcon(entry1IconNew, icon1);
entry1->setIcon(entry1IconNew);
entry1->endUpdate();
// test that we don't overwrite icons
dbTarget->metadata()->addCustomIcon(group2Icon, iconImage2);
dbTarget->metadata()->addCustomIcon(group2Icon, icon1);
dbTarget->metadata()->copyCustomIcons(group1->customIconsRecursive(), dbSource->metadata());
@@ -465,8 +468,8 @@ void TestGroup::testCopyCustomIcons()
QVERIFY(metaTarget->hasCustomIcon(entry1IconOld));
QVERIFY(metaTarget->hasCustomIcon(entry1IconNew));
QCOMPARE(metaTarget->customIcon(group1Icon), iconImage1);
QCOMPARE(metaTarget->customIcon(group2Icon), iconImage2);
QCOMPARE(metaTarget->customIcon(group1Icon), icon1);
QCOMPARE(metaTarget->customIcon(group2Icon), icon1);
}
void TestGroup::testFindEntry()
@@ -1082,7 +1085,7 @@ void TestGroup::testApplyGroupIconRecursively()
QCOMPARE(subgroupEntry->iconUuid(), subgroupIconUuid);
QCOMPARE(subsubgroup->iconUuid(), subgroupIconUuid);
QCOMPARE(subsubgroupEntry->iconUuid(), subgroupIconUuid);
QCOMPARE(subgroup->database()->metadata()->customIcon(subgroupIconUuid), subgroupIcon);
QCOMPARE(subgroup->database()->metadata()->customIcon(subgroupIconUuid).data, subgroupIcon);
// Reset all icons to root icon
database.rootGroup()->setIcon(rootIconNumber);

View File

@@ -116,7 +116,7 @@ void TestKeePass1Reader::testCustomIcons()
QCOMPARE(m_db->metadata()->customIconsOrder().size(), 1);
QUuid uuid = m_db->metadata()->customIconsOrder().at(0);
QVERIFY(m_db->metadata()->hasCustomIcon(uuid));
QByteArray icon = m_db->metadata()->customIcon(uuid);
QByteArray icon = m_db->metadata()->customIcon(uuid).data;
QVERIFY(icon.startsWith(
"\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\xF3\xFF"));

View File

@@ -113,7 +113,7 @@ void TestKeePass2Format::testXmlCustomIcons()
QCOMPARE(m_xmlDb->metadata()->customIconsOrder().size(), 1);
QUuid uuid = QUuid::fromRfc4122(QByteArray::fromBase64("++vyI+daLk6omox4a6kQGA=="));
QVERIFY(m_xmlDb->metadata()->hasCustomIcon(uuid));
QByteArray icon = m_xmlDb->metadata()->customIcon(uuid);
QByteArray icon = m_xmlDb->metadata()->customIcon(uuid).data;
QVERIFY(icon.startsWith(
"\x89PNG\r\n\x1A\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\b\x06\x00\x00\x00\x1F\xF3\xFF"));

View File

@@ -1137,8 +1137,8 @@ void TestMerge::testMergeDuplicateCustomIcons()
QUuid customIconId = QUuid::createUuid();
QByteArray customIcon1 = QString("custom icon 1").toLocal8Bit();
QByteArray customIcon2 = QString("custom icon 2").toLocal8Bit();
QByteArray customIcon1("custom icon 1");
QByteArray customIcon2("custom icon 2");
dbSource->metadata()->addCustomIcon(customIconId, customIcon1);
dbDestination->metadata()->addCustomIcon(customIconId, customIcon2);
@@ -1153,7 +1153,7 @@ void TestMerge::testMergeDuplicateCustomIcons()
QVERIFY(dbDestination->metadata()->hasCustomIcon(customIconId));
QCOMPARE(dbDestination->metadata()->customIconsOrder().count(), 1);
QCOMPARE(dbDestination->metadata()->customIcon(customIconId), customIcon2);
QCOMPARE(dbDestination->metadata()->customIcon(customIconId).data, customIcon2);
}
void TestMerge::testMetadata()