summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Vogel <lukedirtwalker@gmail.com>2018-03-13 15:59:14 +0100
committerLukas Vogel <lukedirtwalker@gmail.com>2018-03-15 10:04:55 +0100
commit5eb8d771b94dce458e7761131b8c0b85e3e127f4 (patch)
tree011fe01ff41f8893db342d5b70dec0f578e18a23
parent11cfe409dbe1bf9f82ab9ecbb7a2928a604dff3c (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.cpp58
-rw-r--r--src/filecontent.h68
-rw-r--r--src/src.pro6
-rw-r--r--tests/auto/util/tst_util.cpp38
-rw-r--r--tests/auto/util/util.pro8
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)