diff --git a/src/keeshare/ShareObserver.cpp b/src/keeshare/ShareObserver.cpp index e8931be1..fc0435f9 100644 --- a/src/keeshare/ShareObserver.cpp +++ b/src/keeshare/ShareObserver.cpp @@ -151,6 +151,12 @@ namespace return {UntrustedOnce, certificate}; } + QString resolvePath(const QString& path, QSharedPointer database) + { + const QFileInfo info(database->filePath()); + return info.absoluteDir().absoluteFilePath(path); + } + } // End Namespace ShareObserver::ShareObserver(QSharedPointer db, QObject* parent) @@ -193,18 +199,20 @@ void ShareObserver::reinitialize() QList updated; const QList groups = m_db->rootGroup()->groupsRecursive(true); for (Group* group : groups) { - Update couple{group, m_groupToReference.value(group), KeeShare::referenceOf(group)}; + const Update couple{group, m_groupToReference.value(group), KeeShare::referenceOf(group)}; if (couple.oldReference == couple.newReference) { continue; } m_groupToReference.remove(couple.group); m_referenceToGroup.remove(couple.oldReference); - m_shareToGroup.remove(couple.oldReference.path); + const auto oldResolvedPath = resolvePath(couple.oldReference.path, m_db); + m_shareToGroup.remove(oldResolvedPath); if (couple.newReference.isValid()) { m_groupToReference[couple.group] = couple.newReference; m_referenceToGroup[couple.newReference] = couple.group; - m_shareToGroup[couple.newReference.path] = couple.group; + const auto newResolvedPath = resolvePath(couple.newReference.path, m_db); + m_shareToGroup[newResolvedPath] = couple.group; } updated << couple; } @@ -216,11 +224,13 @@ void ShareObserver::reinitialize() QMap exported; for (const auto& update : asConst(updated)) { if (!update.oldReference.path.isEmpty()) { - m_fileWatcher->removePath(update.oldReference.path); + const auto oldResolvedPath = resolvePath(update.oldReference.path, m_db); + m_fileWatcher->removePath(oldResolvedPath); } if (!update.newReference.path.isEmpty() && update.newReference.type != KeeShareSettings::Inactive) { - m_fileWatcher->addPath(update.newReference.path); + const auto newResolvedPath = resolvePath(update.newReference.path, m_db); + m_fileWatcher->addPath(newResolvedPath); } if (update.newReference.isExporting()) { exported[update.newReference.path] << update.group->name(); @@ -326,14 +336,16 @@ void ShareObserver::handleFileUpdated(const QString& path) notifyAbout(success, warning, error); } -ShareObserver::Result ShareObserver::importSingedContainerInto(const KeeShareSettings::Reference& reference, +ShareObserver::Result ShareObserver::importSignedContainerInto(const QString& realPath, + const KeeShareSettings::Reference& reference, Group* targetGroup) { #if !defined(WITH_XC_KEESHARE_SECURE) Q_UNUSED(targetGroup); + Q_UNUSED(realPath); return {reference.path, Result::Warning, tr("Signed share container are not supported - import prevented")}; #else - QuaZip zip(reference.path); + QuaZip zip(realPath); if (!zip.open(QuaZip::mdUnzip)) { qCritical("Unable to open file %s.", qPrintable(reference.path)); return {reference.path, Result::Error, tr("File is not readable")}; @@ -438,14 +450,16 @@ ShareObserver::Result ShareObserver::importSingedContainerInto(const KeeShareSet #endif } -ShareObserver::Result ShareObserver::importUnsignedContainerInto(const KeeShareSettings::Reference& reference, +ShareObserver::Result ShareObserver::importUnsignedContainerInto(const QString& realPath, + const KeeShareSettings::Reference& reference, Group* targetGroup) { #if !defined(WITH_XC_KEESHARE_INSECURE) Q_UNUSED(targetGroup); + Q_UNUSED(realPath); return {reference.path, Result::Warning, tr("Unsigned share container are not supported - import prevented")}; #else - QFile file(reference.path); + QFile file(realPath); if (!file.open(QIODevice::ReadOnly)) { qCritical("Unable to open file %s.", qPrintable(reference.path)); return {reference.path, Result::Error, tr("File is not readable")}; @@ -524,20 +538,21 @@ ShareObserver::Result ShareObserver::importUnsignedContainerInto(const KeeShareS #endif } -ShareObserver::Result ShareObserver::importContainerInto(const KeeShareSettings::Reference& reference, +ShareObserver::Result ShareObserver::importContainerInto(const QString& realPath, + const KeeShareSettings::Reference& reference, Group* targetGroup) { - const QFileInfo info(reference.path); + const QFileInfo info(realPath); if (!info.exists()) { qCritical("File %s does not exist.", qPrintable(info.absoluteFilePath())); return {reference.path, Result::Warning, tr("File does not exist")}; } if (isOfExportType(info, KeeShare::signedContainerFileType())) { - return importSingedContainerInto(reference, targetGroup); + return importSignedContainerInto(realPath, reference, targetGroup); } if (isOfExportType(info, KeeShare::unsignedContainerFileType())) { - return importUnsignedContainerInto(reference, targetGroup); + return importUnsignedContainerInto(realPath, reference, targetGroup); } return {reference.path, Result::Error, tr("Unknown share container type")}; } @@ -547,7 +562,8 @@ ShareObserver::Result ShareObserver::importFromReferenceContainer(const QString& if (!KeeShare::active().in) { return {}; } - auto shareGroup = m_shareToGroup.value(path); + const auto changePath = resolvePath(path, m_db); + auto shareGroup = m_shareToGroup.value(changePath); if (!shareGroup) { qWarning("Source for %s does not exist", qPrintable(path)); Q_ASSERT(shareGroup); @@ -565,7 +581,8 @@ ShareObserver::Result ShareObserver::importFromReferenceContainer(const QString& Q_ASSERT(shareGroup->database() == m_db); Q_ASSERT(shareGroup == m_db->rootGroup()->findGroupByUuid(shareGroup->uuid())); - return importContainerInto(reference, shareGroup); + const auto resolvedPath = resolvePath(reference.path, m_db); + return importContainerInto(resolvedPath, reference, shareGroup); } void ShareObserver::resolveReferenceAttributes(Entry* targetEntry, const Database* sourceDb) @@ -603,14 +620,14 @@ Database* ShareObserver::exportIntoContainer(const KeeShareSettings::Reference& // Copy the source root as the root of the export database, memory manage the old root node auto* targetRoot = sourceRoot->clone(Entry::CloneNoFlags, Group::CloneNoFlags); - const bool updateTimeinfo = targetRoot->canUpdateTimeinfo(); + auto updateTimeinfo = targetRoot->canUpdateTimeinfo(); targetRoot->setUpdateTimeinfo(false); KeeShare::setReferenceTo(targetRoot, KeeShareSettings::Reference()); targetRoot->setUpdateTimeinfo(updateTimeinfo); const auto sourceEntries = sourceRoot->entriesRecursive(false); for (const Entry* sourceEntry : sourceEntries) { auto* targetEntry = sourceEntry->clone(Entry::CloneIncludeHistory); - const bool updateTimeinfo = targetEntry->canUpdateTimeinfo(); + updateTimeinfo = targetEntry->canUpdateTimeinfo(); targetEntry->setUpdateTimeinfo(false); targetEntry->setGroup(targetRoot); targetEntry->setUpdateTimeinfo(updateTimeinfo); @@ -647,11 +664,13 @@ QSharedPointer ShareObserver::database() return m_db; } -ShareObserver::Result ShareObserver::exportIntoReferenceSignedContainer(const KeeShareSettings::Reference& reference, +ShareObserver::Result ShareObserver::exportIntoReferenceSignedContainer(const QString& realPath, + const KeeShareSettings::Reference& reference, Database* targetDb) { #if !defined(WITH_XC_KEESHARE_SECURE) Q_UNUSED(targetDb); + Q_UNUSED(realPath); return { reference.path, Result::Warning, tr("Overwriting signed share container is not supported - export prevented")}; #else @@ -667,7 +686,7 @@ ShareObserver::Result ShareObserver::exportIntoReferenceSignedContainer(const Ke } } const auto own = KeeShare::own(); - QuaZip zip(reference.path); + QuaZip zip(realPath); zip.setFileNameCodec("UTF-8"); const bool zipOpened = zip.open(QuaZip::mdCreate); if (!zipOpened) { @@ -723,16 +742,18 @@ ShareObserver::Result ShareObserver::exportIntoReferenceSignedContainer(const Ke #endif } -ShareObserver::Result ShareObserver::exportIntoReferenceUnsignedContainer(const KeeShareSettings::Reference& reference, +ShareObserver::Result ShareObserver::exportIntoReferenceUnsignedContainer(const QString& realPath, + const KeeShareSettings::Reference& reference, Database* targetDb) { #if !defined(WITH_XC_KEESHARE_INSECURE) Q_UNUSED(targetDb); + Q_UNUSED(realPath); return {reference.path, Result::Warning, tr("Overwriting unsigned share container is not supported - export prevented")}; #else - QFile file(reference.path); + QFile file(realPath); const bool fileOpened = file.open(QIODevice::WriteOnly); if (!fileOpened) { ::qWarning("Opening export file failed"); @@ -771,12 +792,12 @@ QList ShareObserver::exportIntoReferenceContainers() for (auto it = references.cbegin(); it != references.cend(); ++it) { if (it.value().count() != 1) { const auto path = it.value().first().config.path; - QStringList groups; + QStringList groupnames; for (const auto& reference : it.value()) { - groups << reference.group->name(); + groupnames << reference.group->name(); } results << Result{ - path, Result::Error, tr("Conflicting export target path %1 in %2").arg(path, groups.join(", "))}; + path, Result::Error, tr("Conflicting export target path %1 in %2").arg(path, groupnames.join(", "))}; } } if (!results.isEmpty()) { @@ -786,16 +807,17 @@ QList ShareObserver::exportIntoReferenceContainers() for (auto it = references.cbegin(); it != references.cend(); ++it) { const auto& reference = it.value().first(); - m_fileWatcher->ignoreFileChanges(reference.config.path); + const QString resolvedPath = resolvePath(reference.config.path, m_db); + m_fileWatcher->ignoreFileChanges(resolvedPath); QScopedPointer targetDb(exportIntoContainer(reference.config, reference.group)); - QFileInfo info(reference.config.path); + QFileInfo info(resolvedPath); if (isOfExportType(info, KeeShare::signedContainerFileType())) { - results << exportIntoReferenceSignedContainer(reference.config, targetDb.data()); + results << exportIntoReferenceSignedContainer(resolvedPath, reference.config, targetDb.data()); m_fileWatcher->observeFileChanges(true); continue; } if (isOfExportType(info, KeeShare::unsignedContainerFileType())) { - results << exportIntoReferenceUnsignedContainer(reference.config, targetDb.data()); + results << exportIntoReferenceUnsignedContainer(resolvedPath, reference.config, targetDb.data()); m_fileWatcher->observeFileChanges(true); continue; } diff --git a/src/keeshare/ShareObserver.h b/src/keeshare/ShareObserver.h index 95c08800..11bf883b 100644 --- a/src/keeshare/ShareObserver.h +++ b/src/keeshare/ShareObserver.h @@ -79,12 +79,20 @@ private: static void resolveReferenceAttributes(Entry* targetEntry, const Database* sourceDb); static Database* exportIntoContainer(const KeeShareSettings::Reference& reference, const Group* sourceRoot); - static Result exportIntoReferenceUnsignedContainer(const KeeShareSettings::Reference& reference, + static Result exportIntoReferenceUnsignedContainer(const QString& realPath, + const KeeShareSettings::Reference& reference, Database* targetDb); - static Result exportIntoReferenceSignedContainer(const KeeShareSettings::Reference& reference, Database* targetDb); - static Result importSingedContainerInto(const KeeShareSettings::Reference& reference, Group* targetGroup); - static Result importUnsignedContainerInto(const KeeShareSettings::Reference& reference, Group* targetGroup); - static Result importContainerInto(const KeeShareSettings::Reference& reference, Group* targetGroup); + static Result exportIntoReferenceSignedContainer(const QString& realPath, + const KeeShareSettings::Reference& reference, + Database* targetDb); + static Result importSignedContainerInto(const QString& realPath, + const KeeShareSettings::Reference& reference, + Group* targetGroup); + static Result importUnsignedContainerInto(const QString& realPath, + const KeeShareSettings::Reference& reference, + Group* targetGroup); + static Result + importContainerInto(const QString& realPath, const KeeShareSettings::Reference& reference, Group* targetGroup); static Result importDatabaseInto(); Result importFromReferenceContainer(const QString& path);