Passwordfile library  3.1.4
C++ library to read/write passwords from/to encrypted files
passwordfiletests.cpp
Go to the documentation of this file.
1 #include "../io/cryptoexception.h"
2 #include "../io/entry.h"
3 #include "../io/passwordfile.h"
4 
5 #include <c++utilities/tests/testutils.h>
6 
7 #include <cppunit/TestFixture.h>
8 #include <cppunit/extensions/HelperMacros.h>
9 
10 using namespace std;
11 using namespace Io;
12 using namespace TestUtilities::Literals;
13 
14 using namespace CPPUNIT_NS;
15 
19 class PasswordFileTests : public TestFixture {
20  CPPUNIT_TEST_SUITE(PasswordFileTests);
21  CPPUNIT_TEST(testReading);
22 #ifdef PLATFORM_UNIX
23  CPPUNIT_TEST(testWriting);
24 #endif
25  CPPUNIT_TEST_SUITE_END();
26 
27 public:
28  void setUp();
29  void tearDown();
30 
31  void testReading();
32  void testReading(
33  const string &testfile1path, const string &testfile1password, const string &testfile2, const string &testfile2password, bool testfile2Mod);
34 #ifdef PLATFORM_UNIX
35  void testWriting();
36 #endif
37 };
38 
40 
42 {
43 }
44 
46 {
47 }
48 
53 {
54  testReading(TestUtilities::testFilePath("testfile1.pwmgr"), "123456", TestUtilities::testFilePath("testfile2.pwmgr"), string(), false);
55 }
56 
58  const string &testfile1path, const string &testfile1password, const string &testfile2, const string &testfile2password, bool testfile2Mod)
59 {
60  PasswordFile file;
61 
62  // open testfile 1 ...
63  file.setPath(testfile1path);
64  file.open(true);
65 
66  CPPUNIT_ASSERT(file.isEncryptionUsed() == !testfile1password.empty());
67  // attempt to decrypt using a wrong password
68  file.setPassword(testfile1password + "asdf");
69  if (!testfile1password.empty()) {
70  CPPUNIT_ASSERT_THROW(file.load(), CryptoException);
71  }
72  // attempt to decrypt using the correct password
73  file.setPassword(testfile1password);
74  file.load();
75  // test root entry
76  const NodeEntry *rootEntry = file.rootEntry();
77  CPPUNIT_ASSERT_EQUAL("testfile1"s, rootEntry->label());
78  CPPUNIT_ASSERT_EQUAL(4_st, rootEntry->children().size());
79 
80  // test testaccount1
81  CPPUNIT_ASSERT_EQUAL("testaccount1"s, rootEntry->children()[0]->label());
82  CPPUNIT_ASSERT(rootEntry->children()[0]->type() == EntryType::Account);
83  CPPUNIT_ASSERT_EQUAL("pin"s, static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(0).name());
84  CPPUNIT_ASSERT_EQUAL("123456"s, static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(0).value());
85  CPPUNIT_ASSERT(static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(0).type() == FieldType::Password);
86  CPPUNIT_ASSERT(
87  static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(0).tiedAccount() == static_cast<AccountEntry *>(rootEntry->children()[0]));
88  CPPUNIT_ASSERT(static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(1).type() == FieldType::Normal);
89  CPPUNIT_ASSERT_THROW(static_cast<AccountEntry *>(rootEntry->children()[0])->fields().at(2), out_of_range);
90 
91  // test testaccount2
92  CPPUNIT_ASSERT_EQUAL("testaccount2"s, rootEntry->children()[1]->label());
93  CPPUNIT_ASSERT(rootEntry->children()[1]->type() == EntryType::Account);
94  CPPUNIT_ASSERT(static_cast<AccountEntry *>(rootEntry->children()[1])->fields().empty());
95 
96  // test testcategory1
97  CPPUNIT_ASSERT_EQUAL("testcategory1"s, rootEntry->children()[2]->label());
98  CPPUNIT_ASSERT(rootEntry->children()[2]->type() == EntryType::Node);
99  const NodeEntry *category = static_cast<NodeEntry *>(rootEntry->children()[2]);
100  CPPUNIT_ASSERT(category->children().size() == 3);
101  CPPUNIT_ASSERT(category->children()[2]->type() == EntryType::Node);
102  CPPUNIT_ASSERT(static_cast<NodeEntry *>(category->children()[2])->children().size() == 2);
103 
104  // test testaccount3
105  CPPUNIT_ASSERT_EQUAL("testaccount3"s, rootEntry->children()[3]->label());
106 
107  // open testfile 2
108  file.setPath(testfile2);
109  file.open(true);
110 
111  CPPUNIT_ASSERT(file.isEncryptionUsed() == !testfile2password.empty());
112  file.setPassword(testfile2password);
113  file.load();
114  rootEntry = file.rootEntry();
115  if (testfile2Mod) {
116  CPPUNIT_ASSERT(rootEntry->label() == "testfile2 - modified");
117  CPPUNIT_ASSERT(rootEntry->children().size() == 2);
118  CPPUNIT_ASSERT(rootEntry->children()[1]->label() == "newAccount");
119  } else {
120  CPPUNIT_ASSERT(rootEntry->label() == "testfile2");
121  CPPUNIT_ASSERT(rootEntry->children().size() == 1);
122  }
123 }
124 
125 #ifdef PLATFORM_UNIX
126 
129 void PasswordFileTests::testWriting()
130 {
131  string testfile1 = TestUtilities::workingCopyPath("testfile1.pwmgr");
132  string testfile2 = TestUtilities::workingCopyPath("testfile2.pwmgr");
133  PasswordFile file;
134 
135  // resave testfile 1
136  file.setPath(testfile1);
137  file.open(false);
138  file.setPassword("123456");
139  file.load();
140  file.doBackup();
141  file.save(false, true);
142 
143  // resave testfile 2
144  file.setPath(testfile2);
145  file.open(false);
146  file.load();
147  file.rootEntry()->setLabel("testfile2 - modified");
148  new AccountEntry("newAccount", file.rootEntry());
149  file.setPassword("654321");
150  file.doBackup();
151  file.save(true, false);
152 
153  // check results using the reading test
154  testReading(testfile1, string(), testfile2, "654321", true);
155 
156  // check backup files
157  testReading(testfile1 + ".backup", "123456", testfile2 + ".backup", string(), false);
158 }
159 #endif
The NodeEntry class acts as parent for other entries.
Definition: entry.h:95
The PasswordFile class holds account information in the form of Entry and Field instances and provide...
Definition: passwordfile.h:18
const std::string & label() const
Returns the label.
Definition: entry.h:62
void setLabel(const std::string &label)
Sets the label.
Definition: entry.h:72
void load()
Reads the contents of the file.
void open(bool readOnly=false)
Opens the file.
STL namespace.
The PasswordFileTests class tests the Io::PasswordFile class.
void doBackup()
Creates a backup of the file.
Contains all IO related classes.
const NodeEntry * rootEntry() const
Returns the root entry if present or nullptr otherwise.
The exception that is thrown when a parsing error occurs.
Definition: entry.h:145
bool isEncryptionUsed()
Returns an indication whether encryption is used if the file is open; returns always false otherwise...
void setPath(const std::string &value)
Sets the current file path.
const std::vector< Entry * > & children() const
Definition: entry.h:125
The exception that is thrown when an encryption/decryption error occurs.
void setPassword(const std::string &value)
Sets the current password.
void testReading()
Tests reading the testfiles testfile{1,2}.pwmgr.
void save(bool useEncryption=true, bool useCompression=true)
Writes the current root entry to the file.
CPPUNIT_TEST_SUITE_REGISTRATION(PasswordFileTests)