Skip to content

Commit

Permalink
Iteration.
Browse files Browse the repository at this point in the history
Signed-off-by: alex-z <[email protected]>
  • Loading branch information
allexzander committed Jul 11, 2023
1 parent 8b6863c commit eb02efe
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 41 deletions.
45 changes: 31 additions & 14 deletions src/libsync/fetchanduploade2eefoldermetadatajob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,24 +74,15 @@ void FetchAndUploadE2eeFolderMetadataJob::uploadMetadata(bool keepLock)

void FetchAndUploadE2eeFolderMetadataJob::lockFolder()
{
Q_ASSERT(!_isFolderLocked);
if (_isFolderLocked) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "already locked";
emit uploadFinished(-1, tr("Error locking folder."));
return;
}

if (!folderMetadata() || !folderMetadata()->isValid()) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "invalid or null metadata";
emit uploadFinished(-1, tr("Error locking folder."));
if (!validateBeforeLock()) {
return;
}

const auto lockJob = new LockEncryptFolderApiJob(_account, _folderId, _journalDb, _account->e2e()->_publicKey, this);
connect(lockJob, &LockEncryptFolderApiJob::success, this, &FetchAndUploadE2eeFolderMetadataJob::slotFolderLockedSuccessfully);
connect(lockJob, &LockEncryptFolderApiJob::error, this, &FetchAndUploadE2eeFolderMetadataJob::slotFolderLockedError);
if (_account->capabilities().clientSideEncryptionVersion() >= 2.0) {
lockJob->setCounter(folderMetadata()->newCounter());
lockJob->setCounter(folderMetadata()->newCounterForTopLevelMetadata());
}
lockJob->start();
}
Expand All @@ -114,6 +105,29 @@ void FetchAndUploadE2eeFolderMetadataJob::fetchFolderEncryptedId()
job->start();
}

bool FetchAndUploadE2eeFolderMetadataJob::validateBeforeLock()
{
//Q_ASSERT(!_isFolderLocked && folderMetadata() && folderMetadata()->isValid() && folderMetadata()->isRootEncryptedFolder());
if (_isFolderLocked) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "already locked";
emit uploadFinished(-1, tr("Error locking folder."));
return false;
}

if (!folderMetadata() || !folderMetadata()->isValid()) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "invalid or null metadata";
emit uploadFinished(-1, tr("Error locking folder."));
return false;
}

if (!folderMetadata()->isRootEncryptedFolder()) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "as it is not a top level folder";
emit uploadFinished(-1, tr("Error locking folder."));
return false;
}
return true;
}

void FetchAndUploadE2eeFolderMetadataJob::slotFolderEncryptedIdReceived(const QStringList &list)
{
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Received id of folder. Fetching metadata...";
Expand Down Expand Up @@ -306,9 +320,12 @@ QSharedPointer<FolderMetadata> FetchAndUploadE2eeFolderMetadataJob::folderMetada

void FetchAndUploadE2eeFolderMetadataJob::setMetadata(const QSharedPointer<FolderMetadata> &metadata)
{
_folderMetadata = metadata;
if (metadata && metadata->isValid() && metadata->counter() == 0) {
_isNewMetadataCreated = true;
Q_ASSERT(metadata && metadata->isValid());
if (metadata && metadata->isValid()) {
_folderMetadata = metadata;
_isNewMetadataCreated = metadata->initialMetadata().isEmpty();
} else {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "setMetadata has invalid argument";
}
}

Expand Down
1 change: 1 addition & 0 deletions src/libsync/fetchanduploade2eefoldermetadatajob.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class OWNCLOUDSYNC_EXPORT FetchAndUploadE2eeFolderMetadataJob : public QObject
void startUploadMetadata();
void startFetchMetadata();
void fetchFolderEncryptedId();
bool validateBeforeLock();

private slots:
void slotFolderEncryptedIdReceived(const QStringList &list);
Expand Down
79 changes: 55 additions & 24 deletions src/libsync/foldermetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ FolderMetadata::FolderMetadata(AccountPtr account,
, _metadataKeyForEncryption(rootEncryptedFolderInfo.keyForEncryption)
, _metadataKeyForDecryption(rootEncryptedFolderInfo.keyForDecryption)
, _keyChecksums(rootEncryptedFolderInfo.keyChecksums)
, _counter(rootEncryptedFolderInfo.counter)
{
setupVersionFromExistingMetadata(metadata);

Expand Down Expand Up @@ -235,9 +234,11 @@ void FolderMetadata::setupExistingMetadata(const QByteArray &metadata)
const auto files = cipherTextDocument.object()[filesKey].toObject();
const auto folders = cipherTextDocument.object()[foldersKey].toObject();

const auto counterVariantFromJson = cipherTextDocument.object()[counterKey].toVariant();
if (counterVariantFromJson.isValid()) {
_counter = cipherTextDocument.object()[counterKey].toVariant().value<quint64>();
if (_isRootEncryptedFolder) {
const auto counterVariantFromJson = cipherTextDocument.object()[counterKey].toVariant();
if (counterVariantFromJson.isValid() && counterVariantFromJson.canConvert<quint64>()) {
_counterForTopLevelMetadata = cipherTextDocument.object()[counterKey].toVariant().value<quint64>();
}
}

for (auto it = files.constBegin(), end = files.constEnd(); it != end; ++it) {
Expand Down Expand Up @@ -617,7 +618,7 @@ QByteArray FolderMetadata::encryptedMetadata()
}

if (_isRootEncryptedFolder) {
cipherText.insert(counterKey, QJsonValue::fromVariant(newCounter()));
cipherText.insert(counterKey, QJsonValue::fromVariant(newCounterForTopLevelMetadata()));
}

const QJsonDocument cipherTextDoc(cipherText);
Expand Down Expand Up @@ -666,20 +667,8 @@ QByteArray FolderMetadata::encryptedMetadata()

auto jsonString = internalMetadata.toJson();

const auto metadataBase64 = jsonString.toBase64();
//----------------------------------------
QByteArray metadatBase64WithBreaks;
int j = 0;
for (int i = 0; i < metadataBase64.size(); ++i) {
metadatBase64WithBreaks += metadataBase64[i];
++j;
if (j > 64) {
j = 0;
metadatBase64WithBreaks += '\n';
}
}
_metadataSignature = _account->e2e()->generateSignatureCMS(metadatBase64WithBreaks).toBase64();
//--------------------------
const auto metadataForSignature = prepareMetadataForSignature(internalMetadata);
_metadataSignature = _account->e2e()->generateSignatureCMS(metadataForSignature.toBase64()).toBase64();

_encryptedMetadataVersion = latestSupportedMetadataVersion();

Expand Down Expand Up @@ -774,14 +763,27 @@ QByteArray FolderMetadata::metadataSignature() const
return _metadataSignature;
}

quint64 FolderMetadata::counter() const
QByteArray FolderMetadata::initialMetadata() const
{
return _counter;
return _initialMetadata;
}

quint64 FolderMetadata::newCounter() const
quint64 FolderMetadata::counterForTopLevelMetadata() const
{
return _counter + 1;
Q_ASSERT(_isRootEncryptedFolder);
if (!_isRootEncryptedFolder) {
qCDebug(lcCseMetadata()) << "Counter is only applicable for top level metadata.";
}
return _counterForTopLevelMetadata;
}

quint64 FolderMetadata::newCounterForTopLevelMetadata() const
{
Q_ASSERT(_isRootEncryptedFolder);
if (!_isRootEncryptedFolder) {
qCDebug(lcCseMetadata()) << "Counter is only applicable for top level metadata.";
}
return _counterForTopLevelMetadata + 1;
}

EncryptionStatusEnums::ItemEncryptionStatus FolderMetadata::fromMedataVersionToItemEncryptionStatus(const MetadataVersion &metadataVersion)
Expand Down Expand Up @@ -812,6 +814,31 @@ FolderMetadata::MetadataVersion FolderMetadata::fromItemEncryptionStatusToMedata
return MetadataVersion::VersionUndefined;
}

QByteArray FolderMetadata::prepareMetadataForSignature(const QJsonDocument &fullMetadata)
{
auto metdataModified = fullMetadata;

auto modifiedObject = metdataModified.object();
modifiedObject.remove(filedropKey);

if (modifiedObject.contains(usersKey)) {
const auto folderUsers = modifiedObject[usersKey].toArray();

QJsonArray modofiedFolderUsers;

for (auto it = folderUsers.constBegin(); it != folderUsers.constEnd(); ++it) {
auto folderUserObject = it->toObject();
folderUserObject.remove(usersEncryptedFiledropKey);
modofiedFolderUsers.push_back(folderUserObject);
modifiedObject.insert(usersKey, folderUserObject);
}
}

metdataModified.setObject(modifiedObject);
auto jsonString = metdataModified.toJson();
return metdataModified.toJson();
}

void FolderMetadata::addEncryptedFile(const EncryptedFile &f) {
Q_ASSERT(_isMetadataValid);
if (!_isMetadataValid) {
Expand Down Expand Up @@ -859,6 +886,11 @@ bool FolderMetadata::isFileDropPresent() const
return !_fileDropCipherTextEncryptedAndBase64.isEmpty();
}

bool FolderMetadata::isRootEncryptedFolder() const
{
return _isRootEncryptedFolder;
}

bool FolderMetadata::encryptedMetadataNeedUpdate() const
{
return latestSupportedMetadataVersion() > _existingMetadataVersion;
Expand Down Expand Up @@ -960,7 +992,6 @@ void FolderMetadata::rootE2eeFolderMetadataReceived(const QJsonDocument &json, i
_metadataKeyForDecryption = rootE2eeFolderMetadata->metadataKeyForDecryption();
_metadataKeyForEncryption = rootE2eeFolderMetadata->metadataKeyForEncryption();
_keyChecksums = rootE2eeFolderMetadata->keyChecksums();
_counter = rootE2eeFolderMetadata->counter();
initMetadata();
});
}
Expand Down
12 changes: 9 additions & 3 deletions src/libsync/foldermetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject

[[nodiscard]] bool isFileDropPresent() const;

[[nodiscard]] bool isRootEncryptedFolder() const;

[[nodiscard]] bool encryptedMetadataNeedUpdate() const;

[[nodiscard]] bool moveFromFileDropToFiles();
Expand All @@ -112,11 +114,13 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject

[[nodiscard]] bool isVersion2AndUp() const;

[[nodiscard]] quint64 counter() const;
[[nodiscard]] quint64 newCounter() const;
[[nodiscard]] quint64 counterForTopLevelMetadata() const;
[[nodiscard]] quint64 newCounterForTopLevelMetadata() const;

[[nodiscard]] QByteArray metadataSignature() const;

[[nodiscard]] QByteArray initialMetadata() const;

private:
QByteArray encryptedMetadataLegacy();

Expand All @@ -141,6 +145,8 @@ class OWNCLOUDSYNC_EXPORT FolderMetadata : public QObject
static EncryptionStatusEnums::ItemEncryptionStatus fromMedataVersionToItemEncryptionStatus(const MetadataVersion &metadataVersion);
static MetadataVersion fromItemEncryptionStatusToMedataVersion(const EncryptionStatusEnums::ItemEncryptionStatus &encryptionStatus);

static QByteArray prepareMetadataForSignature(const QJsonDocument &fullMetadata);

public slots:
void addEncryptedFile(const EncryptedFile &f);
void removeEncryptedFile(const EncryptedFile &f);
Expand Down Expand Up @@ -195,7 +201,7 @@ private slots:

QHash<QString, FolderUser> _folderUsers;

quint64 _counter = 0;
quint64 _counterForTopLevelMetadata = 0;

MetadataVersion _existingMetadataVersion = MetadataVersion::VersionUndefined;
MetadataVersion _encryptedMetadataVersion = MetadataVersion::VersionUndefined;
Expand Down

0 comments on commit eb02efe

Please sign in to comment.