diff options
author | Lukas Vogel <lukedirtwalker@gmail.com> | 2018-03-13 15:59:14 +0100 |
---|---|---|
committer | Lukas Vogel <lukedirtwalker@gmail.com> | 2018-03-15 10:04:55 +0100 |
commit | 5eb8d771b94dce458e7761131b8c0b85e3e127f4 (patch) | |
tree | 011fe01ff41f8893db342d5b70dec0f578e18a23 | |
parent | 11cfe409dbe1bf9f82ab9ecbb7a2928a604dff3c (diff) |
Introduce FileContent class
This can be used to parse the content of the password file in a common
place. In a later commit we should replace the parsing in mainwindow and
passworddialog.
-rw-r--r-- | src/filecontent.cpp | 58 | ||||
-rw-r--r-- | src/filecontent.h | 68 | ||||
-rw-r--r-- | src/src.pro | 6 | ||||
-rw-r--r-- | tests/auto/util/tst_util.cpp | 38 | ||||
-rw-r--r-- | tests/auto/util/util.pro | 8 |
5 files changed, 169 insertions, 9 deletions
diff --git a/src/filecontent.cpp b/src/filecontent.cpp new file mode 100644 index 00000000..409e30b0 --- /dev/null +++ b/src/filecontent.cpp @@ -0,0 +1,58 @@ +#include "filecontent.h" + +FileContent FileContent::parse(const QString &fileContent, const QStringList &templateFields, bool allFields) +{ + QStringList lines = fileContent.split("\n"); + QString password = lines.takeFirst(); + QStringList remainingData; + NamedValues namedValues; + for(QString line : lines) { + if (line.contains(":")) { + int colon = line.indexOf(':'); + QString name = line.left(colon); + QString value = line.right(line.length() - colon - 1); + if ((allFields && !value.startsWith("//")) // if value startswith // colon is probably from a url + || templateFields.contains(name)) { + namedValues.append({name.trimmed(), value.trimmed()}); + continue; + } + } + remainingData.append(line); + } + return FileContent(password, namedValues, remainingData.join("\n")); +} + +QString FileContent::getPassword() const +{ + return this->password; +} + +NamedValues FileContent::getNamedValues() const +{ + return this->namedValues; +} + +QString FileContent::getRemainingData() const +{ + return this->remainingData; +} + +FileContent::FileContent(const QString &password, const NamedValues &namedValues, const QString &remainingData) + : password(password), namedValues(namedValues), remainingData(remainingData) +{} + +NamedValues::NamedValues() : QList() +{} + +NamedValues::NamedValues(std::initializer_list<NamedValue> values) : QList(values) +{} + +QString NamedValues::takeValue(const QString &name) +{ + for (int i = 0; i < length(); ++i) { + if (at(i).name == name) { + return takeAt(i).value; + } + } + return QString(); +} diff --git a/src/filecontent.h b/src/filecontent.h new file mode 100644 index 00000000..7d75ea38 --- /dev/null +++ b/src/filecontent.h @@ -0,0 +1,68 @@ +#ifndef FILECONTENT_H +#define FILECONTENT_H + +#include <utility> +#include <QList> +#include <QString> + +struct NamedValue { + QString name; + QString value; +}; + +/** + * @brief The NamedValues class is mostly a list of \link NamedValue + * but also has a method to take a specific NamedValue pair out of the list. + */ +class NamedValues : public QList<NamedValue> { +public: + NamedValues(); + NamedValues(std::initializer_list<NamedValue> values); + + QString takeValue(const QString &name); +}; + +class FileContent +{ +public: + /** + * @brief parse parses the given fileContent in a FileContent object. + * The password is accessible through getPassword. + * The named value pairs (name: value) are parsed and depeding on the templateFields and allFields parameters + * accessible through getNamedValues or getRemainingData. + * + * @param fileContent the file content to parse. + * + * @param templateFields the fields in the template. + * Fields in the template will always be in getNamedValues() at the beginning of the list in the same order. + * + * @param allFields whether all fields should be considered as named values. + * If set to false only templateFields are returned in getNamedValues(). + * + * @return + */ + static FileContent parse(const QString &fileContent, const QStringList& templateFields, bool allFields); + + /** + * @return the password from the parsed file. + */ + QString getPassword() const; + + /** + * @return the named values in the file in the order of appearence, with template values first. + */ + NamedValues getNamedValues() const; + + /** + * @return the data that is not the password and not in getNamedValues. + */ + QString getRemainingData() const; +private: + FileContent(const QString &password, const NamedValues &namedValues, const QString &remainingData); + + QString password; + NamedValues namedValues; + QString remainingData; +}; + +#endif // FILECONTENT_H diff --git a/src/src.pro b/src/src.pro index a9b69389..7e1dfb52 100644 --- a/src/src.pro +++ b/src/src.pro @@ -22,7 +22,8 @@ SOURCES += mainwindow.cpp \ realpass.cpp \ imitatepass.cpp \ executor.cpp \ - simpletransaction.cpp + simpletransaction.cpp \ + filecontent.cpp HEADERS += mainwindow.h \ configdialog.h \ @@ -44,7 +45,8 @@ HEADERS += mainwindow.h \ datahelpers.h \ debughelper.h \ executor.h \ - simpletransaction.h + simpletransaction.h \ + filecontent.h FORMS += mainwindow.ui \ configdialog.ui \ diff --git a/tests/auto/util/tst_util.cpp b/tests/auto/util/tst_util.cpp index bd1ba906..2a628dc9 100644 --- a/tests/auto/util/tst_util.cpp +++ b/tests/auto/util/tst_util.cpp @@ -1,6 +1,8 @@ #include "../../../src/util.h" +#include "../../../src/filecontent.h" #include <QCoreApplication> #include <QtTest> +#include <QList> /** * @brief The tst_util class is our first unit test @@ -20,8 +22,13 @@ private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void normalizeFolderPath(); + void fileContent(); }; +bool operator==(const NamedValue &a, const NamedValue &b) { + return a.name == b.name && a.value == b.value; +} + /** * @brief tst_util::tst_util basic constructor */ @@ -63,5 +70,36 @@ void tst_util::normalizeFolderPath() { QDir::toNativeSeparators("test/")); } +void tst_util::fileContent() { + NamedValue key = {"key", "val"}; + NamedValue key2 = {"key2", "val2"}; + QString password = "password"; + + FileContent fc = FileContent::parse("password\n", {}, false); + QCOMPARE(fc.getPassword(), password); + QCOMPARE(fc.getNamedValues(), {}); + QCOMPARE(fc.getRemainingData(), QString()); + + fc = FileContent::parse("password", {}, false); + QCOMPARE(fc.getPassword(), password); + QCOMPARE(fc.getNamedValues(), {}); + QCOMPARE(fc.getRemainingData(), QString()); + + fc = FileContent::parse("password\nfoobar\n", {}, false); + QCOMPARE(fc.getPassword(), password); + QCOMPARE(fc.getNamedValues(), {}); + QCOMPARE(fc.getRemainingData(), QString("foobar\n")); + + fc = FileContent::parse("password\nkey: val\nkey2: val2", {"key2"}, false); + QCOMPARE(fc.getPassword(), password); + QCOMPARE(fc.getNamedValues(), {key2}); + QCOMPARE(fc.getRemainingData(), QString("key: val")); + + fc = FileContent::parse("password\nkey: val\nkey2: val2", {"key2"}, true); + QCOMPARE(fc.getPassword(), password); + QCOMPARE(fc.getNamedValues(), NamedValues({key, key2})); + QCOMPARE(fc.getRemainingData(), QString()); +} + QTEST_MAIN(tst_util) #include "tst_util.moc" diff --git a/tests/auto/util/util.pro b/tests/auto/util/util.pro index 4f88ed0e..e47d464f 100644 --- a/tests/auto/util/util.pro +++ b/tests/auto/util/util.pro @@ -7,13 +7,7 @@ SOURCES += tst_util.cpp \ LIBS = -L"$$OUT_PWD/../../../src/$(OBJECTS_DIR)" -lqtpass $$LIBS HEADERS += util.h \ - qtpasssettings.h \ - settingsconstants.h \ - pass.h \ - realpass.h \ - imitatepass.h \ - executor.h \ - simpletransaction.h + filecontent.h OBJ_PATH += ../../../src/$(OBJECTS_DIR) |