1
0
mirror of https://github.com/chylex/Nextcloud-Desktop.git synced 2024-11-25 01:42:47 +01:00
Nextcloud-Desktop/src/libsync/propagatedownloadencrypted.cpp
Roeland Jago Douma ce545b1e47
propage*encrypted Q_UNUSED
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
2018-07-02 12:45:44 +02:00

145 lines
5.3 KiB
C++

#include "propagatedownloadencrypted.h"
#include "clientsideencryptionjobs.h"
Q_LOGGING_CATEGORY(lcPropagateDownloadEncrypted, "nextcloud.sync.propagator.download.encrypted", QtInfoMsg)
namespace OCC {
PropagateDownloadEncrypted::PropagateDownloadEncrypted(OwncloudPropagator *propagator, SyncFileItemPtr item) :
_propagator(propagator), _item(item), _info(_item->_file)
{
}
void PropagateDownloadEncrypted::start() {
checkFolderEncryptedStatus();
}
void PropagateDownloadEncrypted::checkFolderEncryptedStatus()
{
auto getEncryptedStatus = new GetFolderEncryptStatusJob(_propagator->account(), _info.path());
connect(getEncryptedStatus, &GetFolderEncryptStatusJob::encryptStatusFolderReceived,
this, &PropagateDownloadEncrypted::folderStatusReceived);
connect(getEncryptedStatus, &GetFolderEncryptStatusJob::encryptStatusError,
this, &PropagateDownloadEncrypted::folderStatusError);
getEncryptedStatus->start();
}
void PropagateDownloadEncrypted::folderStatusError(int statusCode)
{
qCDebug(lcPropagateDownloadEncrypted) << "Failed to get encrypted status of folder" << statusCode;
}
void PropagateDownloadEncrypted::folderStatusReceived(const QString &folder, bool isEncrypted)
{
qCDebug(lcPropagateDownloadEncrypted) << "Get Folder is Encrypted Received" << folder << isEncrypted;
if (!isEncrypted) {
emit folderStatusNotEncrypted();
return;
}
// Is encrypted Now we need the folder-id
auto job = new LsColJob(_propagator->account(), folder, this);
job->setProperties({"resourcetype", "http://owncloud.org/ns:fileid"});
connect(job, &LsColJob::directoryListingSubfolders,
this, &PropagateDownloadEncrypted::checkFolderId);
connect(job, &LsColJob::finishedWithError,
this, &PropagateDownloadEncrypted::folderIdError);
job->start();
}
void PropagateDownloadEncrypted::folderIdError()
{
qCDebug(lcPropagateDownloadEncrypted) << "Failed to get encrypted metadata of folder";
}
void PropagateDownloadEncrypted::checkFolderId(const QStringList &list)
{
auto job = qobject_cast<LsColJob*>(sender());
const QString folderId = list.first();
qCDebug(lcPropagateDownloadEncrypted) << "Received id of folder" << folderId;
const ExtraFolderInfo &folderInfo = job->_folderInfos.value(folderId);
// Now that we have the folder-id we need it's JSON metadata
auto metadataJob = new GetMetadataApiJob(_propagator->account(), folderInfo.fileId);
connect(metadataJob, &GetMetadataApiJob::jsonReceived,
this, &PropagateDownloadEncrypted::checkFolderEncryptedMetadata);
metadataJob->start();
}
void PropagateDownloadEncrypted::checkFolderEncryptedMetadata(const QJsonDocument &json)
{
qCDebug(lcPropagateDownloadEncrypted) << "Metadata Received reading" <<
csync_instruction_str(_item->_instruction) << _item->_file << _item->_encryptedFileName;
const QString filename = _info.fileName();
auto meta = new FolderMetadata(_propagator->account(), json.toJson(QJsonDocument::Compact));
const QVector<EncryptedFile> files = meta->files();
const QString encryptedFilename = _item->_instruction == CSYNC_INSTRUCTION_NEW ?
_item->_file.section(QLatin1Char('/'), -1) :
_item->_encryptedFileName.section(QLatin1Char('/'), -1);
for (const EncryptedFile &file : files) {
if (encryptedFilename == file.encryptedFilename) {
_encryptedInfo = file;
qCDebug(lcPropagateDownloadEncrypted) << "Found matching encrypted metadata for file, starting download";
emit folderStatusEncrypted();
return;
}
}
emit failed();
qCCritical(lcPropagateDownloadEncrypted) << "Failed to find encrypted metadata information of remote file" << filename;
}
// TODO: Fix this. Exported in the wrong place.
QString createDownloadTmpFileName(const QString &previous);
bool PropagateDownloadEncrypted::decryptFile(QFile& tmpFile)
{
const QString tmpFileName = createDownloadTmpFileName(_item->_file + QLatin1String("_dec"));
qCDebug(lcPropagateDownloadEncrypted) << "Content Checksum Computed starting decryption" << tmpFileName;
tmpFile.close();
QFile _tmpOutput(_propagator->getFilePath(tmpFileName), this);
EncryptionHelper::fileDecryption(_encryptedInfo.encryptionKey,
_encryptedInfo.initializationVector,
&tmpFile,
&_tmpOutput);
qCDebug(lcPropagateDownloadEncrypted) << "Decryption finished" << tmpFile.fileName() << _tmpOutput.fileName();
tmpFile.close();
_tmpOutput.close();
// we decripted the temporary into another temporary, so good bye old one
if (!tmpFile.remove()) {
qCDebug(lcPropagateDownloadEncrypted) << "Failed to remove temporary file" << tmpFile.errorString();
_errorString = tmpFile.errorString();
return false;
}
// Let's fool the rest of the logic into thinking this was the actual download
tmpFile.setFileName(_tmpOutput.fileName());
//TODO: This seems what's breaking the logic.
// Let's fool the rest of the logic into thinking this is the right name of the DAV file
_item->_encryptedFileName = _item->_file;
_item->_file = _item->_file.section(QLatin1Char('/'), 0, -2)
+ QLatin1Char('/') + _encryptedInfo.originalFilename;
return true;
}
QString PropagateDownloadEncrypted::errorString() const
{
return _errorString;
}
}