Skip to content

Commit

Permalink
Enforce ShareObserver to resolve relative paths
Browse files Browse the repository at this point in the history
ShareObserver now uses paths which are resolved relative to the
referencing database.
  • Loading branch information
Christian Kieschnick authored and droidmonkey committed Jun 1, 2019
1 parent 16a11c3 commit 02a6ff5
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 28 deletions.
68 changes: 45 additions & 23 deletions src/keeshare/ShareObserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ namespace
return {UntrustedOnce, certificate};
}

QString resolvedPathWith(const QString& path, const Database& database)
{
const QFileInfo info(database.filePath());
return info.absoluteDir().absoluteFilePath(path);
}

} // End Namespace

ShareObserver::ShareObserver(QSharedPointer<Database> db, QObject* parent)
Expand Down Expand Up @@ -193,18 +199,20 @@ void ShareObserver::reinitialize()
QList<Update> updated;
const QList<Group*> 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 = resolvedPathWith(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 = resolvedPathWith(couple.newReference.path, *m_db);
m_shareToGroup[newResolvedPath] = couple.group;
}
updated << couple;
}
Expand All @@ -216,11 +224,13 @@ void ShareObserver::reinitialize()
QMap<QString, QStringList> exported;
for (const auto& update : asConst(updated)) {
if (!update.oldReference.path.isEmpty()) {
m_fileWatcher->removePath(update.oldReference.path);
const auto oldResolvedPath = resolvedPathWith(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 = resolvedPathWith(update.newReference.path, *m_db);
m_fileWatcher->addPath(newResolvedPath);
}
if (update.newReference.isExporting()) {
exported[update.newReference.path] << update.group->name();
Expand Down Expand Up @@ -322,14 +332,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")};
Expand Down Expand Up @@ -434,14 +446,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")};
Expand Down Expand Up @@ -520,20 +534,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")};
}
Expand All @@ -543,7 +558,8 @@ ShareObserver::Result ShareObserver::importFromReferenceContainer(const QString&
if (!KeeShare::active().in) {
return {};
}
auto shareGroup = m_shareToGroup.value(path);
const auto changePath = resolvedPathWith(path, *m_db);
auto shareGroup = m_shareToGroup.value(changePath);
if (!shareGroup) {
qWarning("Source for %s does not exist", qPrintable(path));
Q_ASSERT(shareGroup);
Expand All @@ -561,7 +577,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 = resolvedPathWith(reference.path, *m_db);
return importContainerInto(resolvedPath, reference, shareGroup);
}

void ShareObserver::resolveReferenceAttributes(Entry* targetEntry, const Database* sourceDb)
Expand Down Expand Up @@ -643,11 +660,13 @@ QSharedPointer<Database> 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
Expand All @@ -663,7 +682,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) {
Expand Down Expand Up @@ -719,16 +738,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");
Expand Down Expand Up @@ -782,16 +803,17 @@ QList<ShareObserver::Result> 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 = resolvedPathWith(reference.config.path, *m_db);
m_fileWatcher->ignoreFileChanges(resolvedPath);
QScopedPointer<Database> 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;
}
Expand Down
18 changes: 13 additions & 5 deletions src/keeshare/ShareObserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,20 @@ private slots:
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);
Expand Down

0 comments on commit 02a6ff5

Please sign in to comment.