Improve OPVault handling and replace test opvault
* Fix various bugs in opvault parsing to include: TOTP parsing, date handling, naming convention, attachments, and multiple url's. * Remove category groups that don't have any entries. * Simplify tests by focusing on the resulting database instead of the parsing mechanics. * Remove proprietary "freddy" opvault in favor of self-made "keepassxc" opvault. * Fix #4069, select opvault file on macOS
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QScopedPointer>
|
||||
#include <QUuid>
|
||||
|
||||
bool OpVaultReader::decryptBandEntry(const QJsonObject& bandEntry,
|
||||
@@ -112,9 +113,12 @@ Entry* OpVaultReader::processBandEntry(const QJsonObject& bandEntry, const QDir&
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto entry = new Entry();
|
||||
QScopedPointer<Entry> entry(new Entry());
|
||||
|
||||
if (bandEntry.contains("category")) {
|
||||
if (bandEntry.contains("trashed") && bandEntry["trashed"].toBool()) {
|
||||
// Send this entry to the recycle bin
|
||||
rootGroup->database()->recycleEntry(entry.data());
|
||||
} else if (bandEntry.contains("category")) {
|
||||
const QJsonValue& categoryValue = bandEntry["category"];
|
||||
if (categoryValue.isString()) {
|
||||
bool found = false;
|
||||
@@ -162,8 +166,7 @@ Entry* OpVaultReader::processBandEntry(const QJsonObject& bandEntry, const QDir&
|
||||
}
|
||||
entry->setUuid(Tools::hexToUuid(uuid));
|
||||
|
||||
if (!fillAttributes(entry, bandEntry)) {
|
||||
delete entry;
|
||||
if (!fillAttributes(entry.data(), bandEntry)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -184,7 +187,7 @@ Entry* OpVaultReader::processBandEntry(const QJsonObject& bandEntry, const QDir&
|
||||
entry->setPassword(data.value("password").toString());
|
||||
}
|
||||
|
||||
for (const auto& fieldValue : data.value("fields").toArray()) {
|
||||
for (const auto fieldValue : data.value("fields").toArray()) {
|
||||
if (!fieldValue.isObject()) {
|
||||
continue;
|
||||
}
|
||||
@@ -208,11 +211,11 @@ Entry* OpVaultReader::processBandEntry(const QJsonObject& bandEntry, const QDir&
|
||||
}
|
||||
const QJsonObject& section = sectionValue.toObject();
|
||||
|
||||
fillFromSection(entry, section);
|
||||
fillFromSection(entry.data(), section);
|
||||
}
|
||||
|
||||
fillAttachments(entry, attachmentDir, entryKey, entryHmacKey);
|
||||
return entry;
|
||||
fillAttachments(entry.data(), attachmentDir, entryKey, entryHmacKey);
|
||||
return entry.take();
|
||||
}
|
||||
|
||||
bool OpVaultReader::fillAttributes(Entry* entry, const QJsonObject& bandEntry)
|
||||
@@ -225,9 +228,9 @@ bool OpVaultReader::fillAttributes(Entry* entry, const QJsonObject& bandEntry)
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray overviewJsonBytes = entOver01.getClearText();
|
||||
QJsonDocument overviewDoc = QJsonDocument::fromJson(overviewJsonBytes);
|
||||
QJsonObject overviewJson = overviewDoc.object();
|
||||
auto overviewJsonBytes = entOver01.getClearText();
|
||||
auto overviewDoc = QJsonDocument::fromJson(overviewJsonBytes);
|
||||
auto overviewJson = overviewDoc.object();
|
||||
|
||||
QString title = overviewJson.value("title").toString();
|
||||
entry->setTitle(title);
|
||||
@@ -236,26 +239,20 @@ bool OpVaultReader::fillAttributes(Entry* entry, const QJsonObject& bandEntry)
|
||||
entry->setUrl(url);
|
||||
|
||||
int i = 1;
|
||||
for (const auto& urlV : overviewJson["URLs"].toArray()) {
|
||||
auto urlName = QString("URL_%1").arg(i);
|
||||
auto urlValue = urlV.toString();
|
||||
if (urlV.isObject()) {
|
||||
const auto& urlObj = urlV.toObject();
|
||||
if (urlObj["l"].isString() && urlObj["u"].isString()) {
|
||||
urlName = urlObj["l"].toString();
|
||||
urlValue = urlObj["u"].toString();
|
||||
} else {
|
||||
continue;
|
||||
for (const auto urlV : overviewJson["URLs"].toArray()) {
|
||||
const auto& urlObj = urlV.toObject();
|
||||
if (urlObj.contains("u")) {
|
||||
auto newUrl = urlObj["u"].toString();
|
||||
if (newUrl != url) {
|
||||
// Add this url if it isn't the base one
|
||||
entry->attributes()->set(QString("KP2A_URL_%1").arg(i), newUrl);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
if (!urlValue.isEmpty() && urlValue != url) {
|
||||
entry->attributes()->set(urlName, urlValue);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList tagsList;
|
||||
for (const auto& tagV : overviewJson["tags"].toArray()) {
|
||||
for (const auto tagV : overviewJson["tags"].toArray()) {
|
||||
if (tagV.isString()) {
|
||||
tagsList << tagV.toString();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user