TestOpVaultReader.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /*
  2. * Copyright (C) 2019 KeePassXC Team <team@keepassxc.org>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 2 or (at your option)
  7. * version 3 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include "TestOpVaultReader.h"
  18. #include "config-keepassx-tests.h"
  19. #include "core/Database.h"
  20. #include "core/Group.h"
  21. #include "core/Metadata.h"
  22. #include "core/Tools.h"
  23. #include "crypto/Crypto.h"
  24. #include "format/OpVaultReader.h"
  25. #include "totp/totp.h"
  26. #include <QJsonArray>
  27. #include <QJsonDocument>
  28. #include <QJsonObject>
  29. #include <QList>
  30. #include <QPair>
  31. #include <QStringList>
  32. #include <QTest>
  33. #include <QUuid>
  34. QTEST_GUILESS_MAIN(TestOpVaultReader)
  35. void TestOpVaultReader::initTestCase()
  36. {
  37. QVERIFY(Crypto::init());
  38. m_opVaultPath = QStringLiteral("%1/%2").arg(KEEPASSX_TEST_DATA_DIR, QStringLiteral("/keepassxc.opvault"));
  39. m_categories = QStringList({QStringLiteral("Login"),
  40. QStringLiteral("Credit Card"),
  41. QStringLiteral("Secure Note"),
  42. QStringLiteral("Identity"),
  43. QStringLiteral("Password"),
  44. QStringLiteral("Tombstone"),
  45. QStringLiteral("Software License"),
  46. QStringLiteral("Bank Account"),
  47. QStringLiteral("Database"),
  48. QStringLiteral("Driver License"),
  49. QStringLiteral("Outdoor License"),
  50. QStringLiteral("Membership"),
  51. QStringLiteral("Passport"),
  52. QStringLiteral("Rewards"),
  53. QStringLiteral("SSN"),
  54. QStringLiteral("Router"),
  55. QStringLiteral("Server"),
  56. QStringLiteral("Email")});
  57. }
  58. void TestOpVaultReader::testReadIntoDatabase()
  59. {
  60. QDir opVaultDir(m_opVaultPath);
  61. OpVaultReader reader;
  62. QScopedPointer<Database> db(reader.readDatabase(opVaultDir, "a"));
  63. QVERIFY(db);
  64. QVERIFY2(!reader.hasError(), qPrintable(reader.errorString()));
  65. // Confirm specific entry details are valid
  66. auto entry = db->rootGroup()->findEntryByPath("/Login/KeePassXC");
  67. QVERIFY(entry);
  68. QCOMPARE(entry->title(), QStringLiteral("KeePassXC"));
  69. QCOMPARE(entry->username(), QStringLiteral("keepassxc"));
  70. QCOMPARE(entry->password(), QStringLiteral("opvault"));
  71. QCOMPARE(entry->url(), QStringLiteral("https://www.keepassxc.org"));
  72. QCOMPARE(entry->notes(), QStringLiteral("KeePassXC Account"));
  73. // Check extra URL's
  74. QCOMPARE(entry->attribute("KP2A_URL_1"), QStringLiteral("https://snapshot.keepassxc.org"));
  75. // Check TOTP
  76. QVERIFY(entry->hasTotp());
  77. // Check attachments
  78. auto attachments = entry->attachments();
  79. QCOMPARE(attachments->keys().count(), 1);
  80. QCOMPARE(*attachments->values().begin(), QByteArray("attachment"));
  81. // Confirm expired entries
  82. entry = db->rootGroup()->findEntryByPath("/Login/Expired Login");
  83. QVERIFY(entry->isExpired());
  84. // Confirm advanced attributes
  85. entry = db->rootGroup()->findEntryByPath("/Credit Card/My Credit Card");
  86. QVERIFY(entry);
  87. auto attr = entry->attributes();
  88. QCOMPARE(attr->value("cardholder name"), QStringLiteral("Team KeePassXC"));
  89. QVERIFY(!attr->value("valid from").isEmpty());
  90. QCOMPARE(attr->value("Additional Details_PIN"), QStringLiteral("1234"));
  91. QVERIFY(attr->isProtected("Additional Details_PIN"));
  92. // Confirm address fields
  93. entry = db->rootGroup()->findEntryByPath("/Identity/Team KeePassXC");
  94. QVERIFY(entry);
  95. attr = entry->attributes();
  96. QCOMPARE(attr->value("address_street"), QStringLiteral("123 Password Lane"));
  97. // Confirm complex passwords
  98. entry = db->rootGroup()->findEntryByPath("/Password/Complex Password");
  99. QVERIFY(entry);
  100. QCOMPARE(entry->password(), QStringLiteral("HfgcHjEL}iO}^3N!?*cv~O:9GJZQ0>oC"));
  101. QVERIFY(entry->hasTotp());
  102. auto totpSettings = entry->totpSettings();
  103. QCOMPARE(totpSettings->digits, static_cast<unsigned int>(8));
  104. QCOMPARE(totpSettings->step, static_cast<unsigned int>(45));
  105. // Confirm trashed entries are sent to the recycle bin
  106. auto recycleBin = db->metadata()->recycleBin();
  107. QVERIFY(recycleBin);
  108. QVERIFY(!recycleBin->isEmpty());
  109. QVERIFY(recycleBin->findEntryByPath("Trashed Password"));
  110. // Confirm created groups align with category names
  111. for (const auto group : db->rootGroup()->children()) {
  112. if (group == recycleBin) {
  113. continue;
  114. }
  115. QVERIFY2(m_categories.contains(group->name()),
  116. qPrintable(QStringLiteral("Invalid group name: %1").arg(group->name())));
  117. // Confirm each group is not empty
  118. QVERIFY2(!group->isEmpty(), qPrintable(QStringLiteral("Group %1 is empty").arg(group->name())));
  119. }
  120. }