mirror of
https://github.com/chylex/Nextcloud-Desktop.git
synced 2025-05-12 23:34:11 +02:00
Properly remove encryption data from JSON of deleted file
This commit is contained in:
parent
a9208f6581
commit
b12066f1aa
@ -43,6 +43,7 @@ set(libsync_SRCS
|
||||
propagateuploadv1.cpp
|
||||
propagateuploadng.cpp
|
||||
propagateremotedelete.cpp
|
||||
propagateremotedeleteencrypted.cpp
|
||||
propagateremotemove.cpp
|
||||
propagateremotemkdir.cpp
|
||||
propagateuploadencrypted.cpp
|
||||
|
@ -1334,6 +1334,16 @@ void FolderMetadata::addEncryptedFile(const EncryptedFile &f) {
|
||||
_files.append(f);
|
||||
}
|
||||
|
||||
void FolderMetadata::removeEncryptedFile(const EncryptedFile &f)
|
||||
{
|
||||
for (int i = 0; i < _files.size(); i++) {
|
||||
if (_files.at(i).originalFilename == f.originalFilename) {
|
||||
_files.removeAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QVector<EncryptedFile> FolderMetadata::files() const {
|
||||
return _files;
|
||||
}
|
||||
|
@ -142,6 +142,7 @@ public:
|
||||
FolderMetadata(AccountPtr account, const QByteArray& metadata = QByteArray(), int statusCode = -1);
|
||||
QByteArray encryptedMetadata();
|
||||
void addEncryptedFile(const EncryptedFile& f);
|
||||
void removeEncryptedFile(const EncryptedFile& f);
|
||||
QVector<EncryptedFile> files() const;
|
||||
|
||||
|
||||
|
@ -81,7 +81,7 @@ void PropagateDownloadEncrypted::checkFolderEncryptedMetadata(const QJsonDocumen
|
||||
|
||||
for (const EncryptedFile &file : files) {
|
||||
qCDebug(lcPropagateDownloadEncrypted) << "file" << filename << file.encryptedFilename << file.originalFilename << file.encryptionKey;
|
||||
if (filename == file.originalFilename) {
|
||||
if (filename == file.encryptedFilename) {
|
||||
_encryptedInfo = file;
|
||||
qCDebug(lcPropagateDownloadEncrypted) << "Found matching encrypted metadata for file, starting download";
|
||||
emit folderStatusEncrypted();
|
||||
|
@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "propagateremotedelete.h"
|
||||
#include "propagateremotedeleteencrypted.h"
|
||||
#include "owncloudpropagator_p.h"
|
||||
#include "account.h"
|
||||
#include "common/asserts.h"
|
||||
@ -65,18 +66,25 @@ void PropagateRemoteDelete::start()
|
||||
if (propagator()->_abortRequested.fetchAndAddRelaxed(0))
|
||||
return;
|
||||
|
||||
|
||||
QString remoteFile = _item->_file;
|
||||
if (!_item->_encryptedFileName.isEmpty()) {
|
||||
remoteFile = _item->_encryptedFileName;
|
||||
// TODO update the JSON metadata
|
||||
auto job = new PropagateRemoteDeleteEncrypted(propagator(), _item, this);
|
||||
connect(job, &PropagateRemoteDeleteEncrypted::finished, this, [this] (bool success) {
|
||||
Q_UNUSED(success) // Should we skip file deletion in case of failure?
|
||||
createDeleteJob(_item->_encryptedFileName);
|
||||
});
|
||||
job->start();
|
||||
} else {
|
||||
createDeleteJob(_item->_file);
|
||||
}
|
||||
}
|
||||
|
||||
qCDebug(lcPropagateRemoteDelete) << "local" << _item->_file << "remote" << remoteFile;
|
||||
void PropagateRemoteDelete::createDeleteJob(const QString &filename)
|
||||
{
|
||||
qCInfo(lcPropagateRemoteDelete) << "Deleting file, local" << _item->_file << "remote" << filename;
|
||||
|
||||
_job = new DeleteJob(propagator()->account(),
|
||||
propagator()->_remoteFolder + remoteFile,
|
||||
this);
|
||||
propagator()->_remoteFolder + filename,
|
||||
this);
|
||||
connect(_job.data(), &DeleteJob::finishedSignal, this, &PropagateRemoteDelete::slotDeleteJobFinished);
|
||||
propagator()->_activeJobList.append(this);
|
||||
_job->start();
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
{
|
||||
}
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
void createDeleteJob(const QString &filename);
|
||||
void abort(PropagatorJob::AbortType abortType) Q_DECL_OVERRIDE;
|
||||
|
||||
bool isLikelyFinishedQuickly() Q_DECL_OVERRIDE { return !_item->isDirectory(); }
|
||||
|
130
src/libsync/propagateremotedeleteencrypted.cpp
Normal file
130
src/libsync/propagateremotedeleteencrypted.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include "propagateremotedeleteencrypted.h"
|
||||
#include "clientsideencryptionjobs.h"
|
||||
#include "clientsideencryption.h"
|
||||
#include "owncloudpropagator.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
#include <QMimeDatabase>
|
||||
#include <QFileInfo>
|
||||
#include <QDir>
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
Q_LOGGING_CATEGORY(PROPAGATE_REMOVE_ENCRYPTED, "nextcloud.sync.propagator.remove.encrypted")
|
||||
|
||||
PropagateRemoteDeleteEncrypted::PropagateRemoteDeleteEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item, QObject *parent)
|
||||
: QObject(parent)
|
||||
, _propagator(propagator)
|
||||
, _item(item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::start()
|
||||
{
|
||||
QFileInfo info(_item->_file);
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Folder is encrypted, let's get the Id from it.";
|
||||
auto job = new LsColJob(_propagator->account(), info.path(), this);
|
||||
job->setProperties({"resourcetype", "http://owncloud.org/ns:fileid"});
|
||||
connect(job, &LsColJob::directoryListingSubfolders, this, &PropagateRemoteDeleteEncrypted::slotFolderEncryptedIdReceived);
|
||||
connect(job, &LsColJob::finishedWithError, this, &PropagateRemoteDeleteEncrypted::taskFailed);
|
||||
job->start();
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::slotFolderEncryptedIdReceived(const QStringList &list)
|
||||
{
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Received id of folder, trying to lock it so we can prepare the metadata";
|
||||
auto job = qobject_cast<LsColJob *>(sender());
|
||||
const ExtraFolderInfo folderInfo = job->_folderInfos.value(list.first());
|
||||
slotTryLock(folderInfo.fileId);
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::slotTryLock(const QByteArray &folderId)
|
||||
{
|
||||
auto lockJob = new LockEncryptFolderApiJob(_propagator->account(), folderId, this);
|
||||
connect(lockJob, &LockEncryptFolderApiJob::success, this, &PropagateRemoteDeleteEncrypted::slotFolderLockedSuccessfully);
|
||||
connect(lockJob, &LockEncryptFolderApiJob::error, this, &PropagateRemoteDeleteEncrypted::taskFailed);
|
||||
lockJob->start();
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::slotFolderLockedSuccessfully(const QByteArray &folderId, const QByteArray &token)
|
||||
{
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Folder id" << folderId << "Locked Successfully for Upload, Fetching Metadata";
|
||||
_folderLocked = true;
|
||||
_folderToken = token;
|
||||
_folderId = folderId;
|
||||
|
||||
auto job = new GetMetadataApiJob(_propagator->account(), _folderId);
|
||||
connect(job, &GetMetadataApiJob::jsonReceived, this, &PropagateRemoteDeleteEncrypted::slotFolderEncryptedMetadataReceived);
|
||||
connect(job, &GetMetadataApiJob::error, this, &PropagateRemoteDeleteEncrypted::taskFailed);
|
||||
job->start();
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::slotFolderEncryptedMetadataReceived(const QJsonDocument &json, int statusCode)
|
||||
{
|
||||
if (statusCode == 404) {
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Metadata not found, ignoring.";
|
||||
unlockFolder();
|
||||
return;
|
||||
}
|
||||
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Metadata Received, Preparing it for the new file.";
|
||||
|
||||
// Encrypt File!
|
||||
FolderMetadata metadata(_propagator->account(), json.toJson(QJsonDocument::Compact), statusCode);
|
||||
|
||||
QFileInfo info(_propagator->_localDir + QDir::separator() + _item->_file);
|
||||
const QString fileName = info.fileName();
|
||||
|
||||
// Find existing metadata for this file
|
||||
bool found = false;
|
||||
const QVector<EncryptedFile> files = metadata.files();
|
||||
for (const EncryptedFile &file : files) {
|
||||
if (file.encryptedFilename == fileName) {
|
||||
metadata.removeEncryptedFile(file);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// The removed file was not in the JSON so nothing else to do
|
||||
unlockFolder();
|
||||
}
|
||||
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Metadata updated, sending to the server.";
|
||||
|
||||
auto job = new UpdateMetadataApiJob(_propagator->account(),
|
||||
_folderId,
|
||||
metadata.encryptedMetadata(),
|
||||
_folderToken);
|
||||
|
||||
connect(job, &UpdateMetadataApiJob::success, this, &PropagateRemoteDeleteEncrypted::unlockFolder);
|
||||
connect(job, &UpdateMetadataApiJob::error, this, &PropagateRemoteDeleteEncrypted::taskFailed);
|
||||
job->start();
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::unlockFolder()
|
||||
{
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Unlocking folder" << _folderId;
|
||||
auto unlockJob = new UnlockEncryptFolderApiJob(_propagator->account(),
|
||||
_folderId, _folderToken, this);
|
||||
|
||||
connect(unlockJob, &UnlockEncryptFolderApiJob::success, [this] {
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Folder successfully unlocked" << _folderId;
|
||||
_folderLocked = false;
|
||||
emit finished(true);
|
||||
});
|
||||
connect(unlockJob, &UnlockEncryptFolderApiJob::error, this, &PropagateRemoteDeleteEncrypted::taskFailed);
|
||||
unlockJob->start();
|
||||
}
|
||||
|
||||
void PropagateRemoteDeleteEncrypted::taskFailed()
|
||||
{
|
||||
qCDebug(PROPAGATE_REMOVE_ENCRYPTED) << "Task failed of job" << sender();
|
||||
if (_folderLocked) {
|
||||
unlockFolder();
|
||||
} else {
|
||||
emit finished(false);
|
||||
}
|
||||
}
|
40
src/libsync/propagateremotedeleteencrypted.h
Normal file
40
src/libsync/propagateremotedeleteencrypted.h
Normal file
@ -0,0 +1,40 @@
|
||||
#ifndef PROPAGATEREMOTEDELETEENCRYPTED_H
|
||||
#define PROPAGATEREMOTEDELETEENCRYPTED_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
#include "syncfileitem.h"
|
||||
|
||||
namespace OCC {
|
||||
|
||||
class OwncloudPropagator;
|
||||
class PropagateRemoteDeleteEncrypted : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PropagateRemoteDeleteEncrypted(OwncloudPropagator *_propagator, SyncFileItemPtr item, QObject *parent);
|
||||
|
||||
void start();
|
||||
|
||||
signals:
|
||||
void finished(bool success);
|
||||
|
||||
private:
|
||||
void slotFolderEncryptedIdReceived(const QStringList &list);
|
||||
void slotTryLock(const QByteArray &folderId);
|
||||
void slotFolderLockedSuccessfully(const QByteArray &fileId, const QByteArray &token);
|
||||
void slotFolderEncryptedMetadataReceived(const QJsonDocument &json, int statusCode);
|
||||
void unlockFolder();
|
||||
void taskFailed();
|
||||
|
||||
OwncloudPropagator *_propagator;
|
||||
SyncFileItemPtr _item;
|
||||
QByteArray _folderToken;
|
||||
QByteArray _folderId;
|
||||
bool _folderLocked = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PROPAGATEREMOTEDELETEENCRYPTED_H
|
@ -424,6 +424,7 @@ int SyncEngine::treewalkFile(csync_file_stat_t *file, csync_file_stat_t *other,
|
||||
item->_file = fileUtf8;
|
||||
}
|
||||
item->_originalFile = item->_file;
|
||||
item->_encryptedFileName = file->e2eMangledName;
|
||||
|
||||
if (item->_instruction == CSYNC_INSTRUCTION_NONE
|
||||
|| (item->_instruction == CSYNC_INSTRUCTION_IGNORE && instruction != CSYNC_INSTRUCTION_NONE)) {
|
||||
|
Loading…
Reference in New Issue
Block a user