Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/common/remoteinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ struct RemoteInfo
bool _isE2eEncrypted = false;
bool isFileDropDetected = false;
QString e2eMangledName;
QByteArray _e2eFileEncryptionKey;
QByteArray _initializationVector;
QByteArray _authenticationTag;
bool sharedByMe = false;

[[nodiscard]] bool isValid() const { return !name.isNull(); }
Expand Down
22 changes: 18 additions & 4 deletions src/common/syncjournaldb.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#include <QCryptographicHash>

Check failure on line 7 in src/common/syncjournaldb.cpp

View workflow job for this annotation

GitHub Actions / build

src/common/syncjournaldb.cpp:7:10 [clang-diagnostic-error]

'QCryptographicHash' file not found
#include <QFile>
#include <QJsonArray>
#include <QJsonDocument>
Expand Down Expand Up @@ -45,7 +45,7 @@
"SELECT path, inode, modtime, type, md5, fileid, remotePerm, filesize," \
" ignoredChildrenRemote, contentchecksumtype.name || ':' || contentChecksum, e2eMangledName, isE2eEncrypted, e2eCertificateFingerprint, " \
" lock, lockOwnerDisplayName, lockOwnerId, lockType, lockOwnerEditor, lockTime, lockTimeout, lockToken, isShared, lastShareStateFetchedTimestmap, " \
" sharedByMe, isLivePhoto, livePhotoFile, quotaBytesUsed, quotaBytesAvailable" \
" sharedByMe, isLivePhoto, livePhotoFile, quotaBytesUsed, quotaBytesAvailable, e2eFileEncryptionKey, authenticationTag, initializationVector" \
" FROM metadata" \
" LEFT JOIN checksumtype as contentchecksumtype ON metadata.contentChecksumTypeId == contentchecksumtype.id"

Expand All @@ -63,6 +63,9 @@
rec._checksumHeader = query.baValue(9);
rec._e2eMangledName = query.baValue(10);
rec._e2eEncryptionStatus = static_cast<SyncJournalFileRecord::EncryptionStatus>(query.intValue(11));
rec._e2eFileEncryptionKey = query.baValue(28);
rec._authenticationTag = query.baValue(29);
rec._initializationVector = query.baValue(30);
rec._lockstate._locked = query.intValue(13) > 0;
rec._lockstate._lockOwnerDisplayName = query.stringValue(14);
rec._lockstate._lockOwnerId = query.stringValue(15);
Expand Down Expand Up @@ -894,7 +897,7 @@
addColumn(QStringLiteral("isLivePhoto"), QStringLiteral("INTEGER"));
addColumn(QStringLiteral("livePhotoFile"), QStringLiteral("TEXT"));

{

Check warning on line 900 in src/common/syncjournaldb.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Extract this nested code block into a separate function.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKmJSuFLwgU57buL&open=AZ9rsKmJSuFLwgU57buL&pullRequest=10286
const auto quotaBytesUsed = QStringLiteral("quotaBytesUsed");
const auto quotaBytesAvailable = QStringLiteral("quotaBytesAvailable");
const auto defaultCommand = QStringLiteral("DEFAULT -1 NOT NULL");
Expand All @@ -917,6 +920,10 @@
addColumn(quotaBytesAvailable, bigInt, false, defaultCommand);
}

addColumn(u"e2eFileEncryptionKey"_s, u"TEXT"_s);
addColumn(u"authenticationTag"_s, u"TEXT"_s);
addColumn(u"initializationVector"_s, u"TEXT"_s);

return re;
}

Expand Down Expand Up @@ -1078,9 +1085,13 @@

const auto query = _queryManager.get(PreparedSqlQueryManager::SetFileRecordQuery, QByteArrayLiteral("INSERT OR REPLACE INTO metadata "
"(phash, pathlen, path, inode, uid, gid, mode, modtime, type, md5, fileid, remotePerm, filesize, ignoredChildrenRemote, "
"contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted, e2eCertificateFingerprint, lock, lockType, lockOwnerDisplayName, lockOwnerId, "
"lockOwnerEditor, lockTime, lockTimeout, lockToken, isShared, lastShareStateFetchedTimestmap, sharedByMe, isLivePhoto, livePhotoFile, quotaBytesUsed, quotaBytesAvailable) "
"VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33, ?34);"),
"contentChecksum, contentChecksumTypeId, e2eMangledName, isE2eEncrypted, e2eCertificateFingerprint, "
"lock, lockType, lockOwnerDisplayName, lockOwnerId, "
"lockOwnerEditor, lockTime, lockTimeout, lockToken, isShared, lastShareStateFetchedTimestmap, "
"sharedByMe, isLivePhoto, livePhotoFile, quotaBytesUsed, quotaBytesAvailable, "
"e2eFileEncryptionKey, authenticationTag, initializationVector) "
"VALUES (?1 , ?2, ?3 , ?4 , ?5 , ?6 , ?7, ?8 , ?9 , ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, "
"?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33, ?34, ?35, ?36, ?37);"),
_db);
if (!query) {
qCWarning(lcDb) << "database error:" << query->error();
Expand All @@ -1106,6 +1117,9 @@
query->bindValue(17, record._e2eMangledName);
query->bindValue(18, static_cast<int>(record._e2eEncryptionStatus));
query->bindValue(19, {});
query->bindValue(35, record._e2eFileEncryptionKey);
query->bindValue(36, record._authenticationTag);
query->bindValue(37, record._initializationVector);
query->bindValue(20, record._lockstate._locked ? 1 : 0);
query->bindValue(21, record._lockstate._lockOwnerType);
query->bindValue(22, record._lockstate._lockOwnerDisplayName);
Expand Down Expand Up @@ -1229,7 +1243,7 @@
auto pathComponents = parentPath.split(QLatin1Char('/'));
while (!pathComponents.isEmpty()) {
const auto pathCompontentsJointed = pathComponents.join(QLatin1Char('/'));
if (!getFileRecord(pathCompontentsJointed, rec)) {

Check warning on line 1246 in src/common/syncjournaldb.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the init-statement to declare "pathCompontentsJointed" inside the if statement.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKmJSuFLwgU57buT&open=AZ9rsKmJSuFLwgU57buT&pullRequest=10286
qCWarning(lcDb) << "could not get file from local DB" << pathCompontentsJointed;
return false;
}
Expand Down Expand Up @@ -2440,7 +2454,7 @@
commitInternal(QStringLiteral("setSelectiveSyncList"));
}

QStringList SyncJournalDb::addSelectiveSyncLists(SelectiveSyncListType type, const QString &path)

Check warning on line 2457 in src/common/syncjournaldb.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "type" of type "enum OCC::SyncJournalDb::SelectiveSyncListType" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKmJSuFLwgU57buY&open=AZ9rsKmJSuFLwgU57buY&pullRequest=10286
{
bool ok = false;

Expand Down
3 changes: 3 additions & 0 deletions src/common/syncjournalfilerecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef SYNCJOURNALFILERECORD_H
#define SYNCJOURNALFILERECORD_H

#include <QString>

Check failure on line 10 in src/common/syncjournalfilerecord.h

View workflow job for this annotation

GitHub Actions / build

src/common/syncjournalfilerecord.h:10:10 [clang-diagnostic-error]

'QString' file not found
#include <QDateTime>

#include "csync.h"
Expand Down Expand Up @@ -72,6 +72,9 @@
QByteArray _checksumHeader;
QByteArray _e2eMangledName;
EncryptionStatus _e2eEncryptionStatus = EncryptionStatus::NotEncrypted;
QByteArray _e2eFileEncryptionKey;
QByteArray _initializationVector;
QByteArray _authenticationTag;
SyncJournalFileLockInfo _lockstate;
bool _isShared = false;
qint64 _lastShareStateFetchedTimestamp = 0;
Expand Down
53 changes: 52 additions & 1 deletion src/gui/accountsettings.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
Expand Down Expand Up @@ -31,6 +31,7 @@
#include "tooltipupdater.h"
#include "filesystem.h"
#include "encryptfolderjob.h"
#include "repairfolderencryptionmetadatajob.h"
#include "syncresult.h"
#include "ignorelisttablewidget.h"
#include "networksettings.h"
Expand Down Expand Up @@ -190,7 +191,7 @@
_ui->accountStatusLayout->removeWidget(_ui->encryptionMessage);
encryptionPanelLayout->addWidget(_ui->encryptionMessage);

auto *connectionSettingsButton = new QPushButton(tr("Connection settings"), _ui->accountStatus);

Check warning on line 194 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "connectionSettingsButton" of type "class QPushButton *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bmu&open=AZ9rsKQFSuFLwgU57bmu&pullRequest=10286
connectionSettingsButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
_ui->gridLayout_2->addWidget(connectionSettingsButton, 0, 2, Qt::AlignRight | Qt::AlignVCenter);
connect(connectionSettingsButton, &QPushButton::clicked, this, &AccountSettings::showConnectionSettingsDialog);
Expand Down Expand Up @@ -417,6 +418,25 @@
job->deleteLater();
}

void AccountSettings::slotRepairEncryptedFolderFinished(int status)

Check warning on line 421 in src/gui/accountsettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.cpp:421:23 [readability-convert-member-functions-to-static]

method 'slotRepairEncryptedFolderFinished' can be made static
{
qCInfo(lcAccountSettings) << "Current folder encryption status code:" << status;
auto job = qobject_cast<RepairFolderEncryptionMetadataJob*>(sender());
Q_ASSERT(job);
if (!job->errorString().isEmpty()) {
QMessageBox::warning(nullptr, tr("Repair of encryption failed"), job->errorString());
}

const auto folder = job->property(propertyFolder).value<Folder *>();
Q_ASSERT(folder);
const auto path = job->property(propertyPath).toString();
const auto index = _model->indexForPath(folder, path);
Q_ASSERT(index.isValid());
_model->resetAndFetch(index.parent());

job->deleteLater();
}

QString AccountSettings::selectedFolderAlias() const
{
const auto selected = _ui->_folderList->selectionModel()->currentIndex();
Expand Down Expand Up @@ -523,7 +543,7 @@

const auto folderAlias = folder->alias();
const auto path = folderInfo->_path;
const auto fileId = folderInfo->_fileId;

Check warning on line 546 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Avoid this unnecessary copy by using a "const" reference.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bm0&open=AZ9rsKQFSuFLwgU57bm0&pullRequest=10286
const auto encryptFolder = [this, fileId, path, folderAlias] {
const auto folder = FolderMan::instance()->folder(folderAlias);
if (!folder) {
Expand Down Expand Up @@ -552,6 +572,33 @@
showEnableE2eeWarningDialog(encryptFolder);
}

void AccountSettings::slotRepairEncryptedSubfolder(FolderStatusModel::SubFolderInfo *folderInfo)

Check warning on line 575 in src/gui/accountsettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.cpp:575:23 [readability-convert-member-functions-to-static]

method 'slotRepairEncryptedSubfolder' can be made static

Check warning on line 575 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "folderInfo" of type "struct OCC::FolderStatusModel::SubFolderInfo *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bm2&open=AZ9rsKQFSuFLwgU57bm2&pullRequest=10286
{
const auto folder = folderInfo->_folder;

Check warning on line 577 in src/gui/accountsettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.cpp:577:5 [readability-qualified-auto]

'const auto folder' can be declared as 'auto *const folder'
Q_ASSERT(folder);

const auto folderAlias = folder->alias();
const auto path = folderInfo->_path;

Check warning on line 581 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Avoid this unnecessary copy by using a "const" reference.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bm3&open=AZ9rsKQFSuFLwgU57bm3&pullRequest=10286
const auto fileId = folderInfo->_fileId;

if (!folder) {

Check warning on line 584 in src/gui/accountsettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.cpp:584:10 [readability-implicit-bool-conversion]

implicit conversion 'OCC::Folder *' -> bool
qCWarning(lcAccountSettings) << "Could not repair encrypted folder because folder" << folderAlias << "does not exist anymore";
QMessageBox::warning(nullptr, tr("Repair of encryption failed"), tr("Could not repair encryption because the folder does not exist anymore"));
return;
}

// Folder info have directory paths in Foo/Bar/ convention...
Q_ASSERT(!path.startsWith('/') && path.endsWith('/'));
// But EncryptFolderJob expects directory path Foo/Bar convention
const auto choppedPath = path.chopped(1);
auto job = new RepairFolderEncryptionMetadataJob(accountsState()->account(), folder->journalDb(), choppedPath, choppedPath, folder->remotePath(), fileId);

Check warning on line 594 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "job" of type "class OCC::RepairFolderEncryptionMetadataJob *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bm5&open=AZ9rsKQFSuFLwgU57bm5&pullRequest=10286
job->setParent(this);
job->setProperty(propertyFolder, QVariant::fromValue(folder));
job->setProperty(propertyPath, QVariant::fromValue(path));
connect(job, &RepairFolderEncryptionMetadataJob::finished, this, &AccountSettings::slotRepairEncryptedFolderFinished);
job->start();
}

void AccountSettings::slotEditCurrentIgnoredFiles()
{
const auto folder = FolderMan::instance()->folder(selectedFolderAlias());
Expand Down Expand Up @@ -675,6 +722,10 @@
// Ignore decrypting for now since it only works with an empty folder
// connect(ac, &QAction::triggered, [this, &info] { slotMarkSubfolderDecrypted(info); });
}
if (isEncrypted && _accountState->account()->e2e()->isInitialized()) {
ac = menu.addAction(tr("Repair encryption"));
connect(ac, &QAction::triggered, [this, info] { slotRepairEncryptedSubfolder(info); });
}
}

ac = menu.addAction(tr("Edit Ignored Files"));
Expand Down Expand Up @@ -1262,14 +1313,14 @@
ui.lineEdit->selectAll();
ui.lineEdit->setAlignment(Qt::AlignCenter);

const QFont font(QStringLiteral(""), 0);
const QFont font(QLatin1String{}, 0);

Check warning on line 1316 in src/gui/accountsettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.cpp:1316:17 [cppcoreguidelines-init-variables]

variable 'font' is not initialized
QFontMetrics fm(font);
ui.lineEdit->setFixedWidth(fm.horizontalAdvance(mnemonic));
widget.resize(widget.sizeHint());
widget.exec();
}

void AccountSettings::forgetEncryptionOnDeviceForAccount(const AccountPtr &account) const

Check warning on line 1323 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bm-&open=AZ9rsKQFSuFLwgU57bm-&pullRequest=10286
{
QMessageBox dialog;
dialog.setWindowTitle(tr("Forget the end-to-end encryption on this device"));
Expand Down Expand Up @@ -1537,7 +1588,7 @@
.arg(Utility::escape(Theme::instance()->appNameGUI())));
}

const auto isPublicShareLink = _accountState->account()->isPublicShareLink();

Check failure on line 1591 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Called C++ object pointer is null

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bnO&open=AZ9rsKQFSuFLwgU57bnO&pullRequest=10286
_ui->_toggleSignInOutButton->setVisible(!isPublicShareLink);
_ui->_toggleSignInOutButton->setText(_accountState->isSignedOut() ? tr("Log in") : tr("Log out"));
_ui->_removeAccountButton->setText(isPublicShareLink ? tr("Leave share") : tr("Remove account"));
Expand Down Expand Up @@ -1599,7 +1650,7 @@
const auto li = link.split(QLatin1String("?folder="));
if (li.count() > 1) {
auto myFolder = li[0];
const auto alias = li[1];

Check warning on line 1653 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Avoid this unnecessary copy by using a "const" reference.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bnF&open=AZ9rsKQFSuFLwgU57bnF&pullRequest=10286
if (myFolder.endsWith(QLatin1Char('/'))) {
myFolder.chop(1);
}
Expand Down Expand Up @@ -2060,7 +2111,7 @@
stretchIndex = layout->count() - 1;
}

for (QAction *action : actions) {

Check warning on line 2114 in src/gui/accountsettings.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "action" of type "class QAction *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKQFSuFLwgU57bnM&open=AZ9rsKQFSuFLwgU57bnM&pullRequest=10286
auto *button = new QPushButton(_ui->encryptionMessage);
button->setText(action->text());
button->setIcon(action->icon());
Expand Down
2 changes: 2 additions & 0 deletions src/gui/accountsettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef ACCOUNTSETTINGS_H
#define ACCOUNTSETTINGS_H

#include <QWidget>

Check failure on line 10 in src/gui/accountsettings.h

View workflow job for this annotation

GitHub Actions / build

src/gui/accountsettings.h:10:10 [clang-diagnostic-error]

'QWidget' file not found
#include <QUrl>
#include <QPointer>
#include <QHash>
Expand Down Expand Up @@ -105,6 +105,7 @@
void slotToggleSignInState();
void refreshSelectiveSyncStatus();
void slotMarkSubfolderEncrypted(OCC::FolderStatusModel::SubFolderInfo *folderInfo);
void slotRepairEncryptedSubfolder(OCC::FolderStatusModel::SubFolderInfo *folderInfo);
void slotSubfolderContextMenuRequested(const QModelIndex& idx, const QPoint& point);
void slotCustomContextMenuRequested(const QPoint &);
void slotFolderListClicked(const QModelIndex &indx);
Expand All @@ -116,6 +117,7 @@
void slotE2eEncryptionGenerateKeys();
void slotE2eEncryptionInitializationFinished(bool isNewMnemonicGenerated);
void slotEncryptFolderFinished(int status);
void slotRepairEncryptedFolderFinished(int status);

void slotSelectiveSyncChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
const QVector<int> &roles);
Expand Down
2 changes: 1 addition & 1 deletion src/gui/folder.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
Expand All @@ -7,7 +7,7 @@
#ifndef MIRALL_FOLDER_H
#define MIRALL_FOLDER_H

#include "syncresult.h"

Check failure on line 10 in src/gui/folder.h

View workflow job for this annotation

GitHub Actions / build

src/gui/folder.h:10:10 [clang-diagnostic-error]

'syncresult.h' file not found
#include "progressdispatcher.h"
#include "common/syncjournaldb.h"
#include "networkjobs.h"
Expand Down Expand Up @@ -392,7 +392,7 @@
void slotTerminateSync();

// connected to the corresponding signals in the SyncEngine
void slotAboutToRemoveAllFiles(OCC::SyncFileItem::Direction, std::function<void(bool)> callback);
void slotAboutToRemoveAllFiles(OCC::SyncFileItem::Direction, std::function<void(bool)> callback);// clazy:exclude=fully-qualified-moc-types

/**
* Starts a sync operation
Expand Down
2 changes: 1 addition & 1 deletion src/gui/owncloudgui.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2013 ownCloud GmbH
Expand Down Expand Up @@ -97,7 +97,7 @@
* to the folder).
*/
void slotShowShareDialog(const QString &localPath) const;
void slotShowGovernanceLabelsDialog(AccountPtr account,
void slotShowGovernanceLabelsDialog(OCC::AccountPtr account,
const QString &localPath,
const QString &fileId) const;
void slotShowFileActivityDialog(const QString &localPath) const;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/systray.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public slots:
void createEditFileLocallyLoadingDialog(const QString &fileName);
void destroyEditFileLocallyLoadingDialog();
void createResolveConflictsDialog(const OCC::ActivityList &allConflicts);
void createGovernanceLabelsDialog(AccountPtr account, const QString &fileName, const QString &fileId);
void createGovernanceLabelsDialog(OCC::AccountPtr account, const QString &fileName, const QString &fileId);
void createEncryptionTokenDiscoveryDialog();
void destroyEncryptionTokenDiscoveryDialog();

Expand Down
4 changes: 2 additions & 2 deletions src/gui/tray/usermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#ifndef USERMODEL_H
#define USERMODEL_H

#include <QAbstractListModel>

Check failure on line 9 in src/gui/tray/usermodel.h

View workflow job for this annotation

GitHub Actions / build

src/gui/tray/usermodel.h:9:10 [clang-diagnostic-error]

'QAbstractListModel' file not found
#include <QImage>
#include <QDateTime>
#include <QJsonDocument>
Expand Down Expand Up @@ -233,8 +233,8 @@
private slots:
void slotPushNotificationsReady();
void slotDisconnectPushNotifications();
void slotReceivedPushFilesChanges(Account *account);
void slotReceivedPushFileIdsChanges(Account *account, const QList<qint64> &fileIds);
void slotReceivedPushFilesChanges(OCC::Account *account);
void slotReceivedPushFileIdsChanges(OCC::Account *account, const QList<qint64> &fileIds);
void slotReceivedPushNotification(OCC::Account *account);
void slotReceivedPushActivity(OCC::Account *account);
void slotCheckExpiredActivities();
Expand Down Expand Up @@ -307,7 +307,7 @@
// no query for notifications is started.
int _notificationRequestsRunning = 0;

int _lastTalkNotificationsReceivedCount = 0;

Check warning on line 310 in src/gui/tray/usermodel.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9wr94F8T1mUZ_7CSAR&open=AZ9wr94F8T1mUZ_7CSAR&pullRequest=10286

bool _isNotificationFetchRunning = false;

Expand Down
2 changes: 2 additions & 0 deletions src/libsync/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ set(libsync_SRCS
clientsideencryptionprimitives.cpp
clientsideencryptiontokenselector.h
clientsideencryptiontokenselector.cpp
repairfolderencryptionmetadatajob.h
repairfolderencryptionmetadatajob.cpp
datetimeprovider.h
datetimeprovider.cpp
rootencryptedfolderinfo.h
Expand Down
8 changes: 4 additions & 4 deletions src/libsync/clientsideencryption.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
Expand All @@ -6,7 +6,7 @@
#ifndef CLIENTSIDEENCRYPTION_H
#define CLIENTSIDEENCRYPTION_H

#include "owncloudlib.h"

Check failure on line 9 in src/libsync/clientsideencryption.h

View workflow job for this annotation

GitHub Actions / build

src/libsync/clientsideencryption.h:9:10 [clang-diagnostic-error]

'owncloudlib.h' file not found

#include "clientsideencryptionprimitives.h"
#include "accountfwd.h"
Expand Down Expand Up @@ -220,7 +220,7 @@
NextcloudSslCertificate(QSslCertificate &&certificate);

operator QSslCertificate();
operator QSslCertificate() const;

Check failure on line 223 in src/libsync/clientsideencryption.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this conversion operator with a function or (C++11) add the "explicit" keyword.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKYsSuFLwgU57bo8&open=AZ9rsKYsSuFLwgU57bo8&pullRequest=10286

QSslCertificate& get();
const QSslCertificate &get() const;
Expand Down Expand Up @@ -306,7 +306,7 @@
void certificatesFetchedFromServer(const QHash<QString, OCC::NextcloudSslCertificate> &results);
void certificateWriteComplete(const QSslCertificate &certificate);

void startingDiscoveryEncryptionUsbToken();

Check warning on line 309 in src/libsync/clientsideencryption.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKYsSuFLwgU57bpC&open=AZ9rsKYsSuFLwgU57bpC&pullRequest=10286
void finishedDiscoveryEncryptionUsbToken();

void canEncryptChanged();
Expand Down Expand Up @@ -334,10 +334,10 @@
void privateKeyFetched(QKeychain::Job *incoming);
void mnemonicKeyFetched(QKeychain::Job *incoming);

void handlePrivateKeyDeleted(const QKeychain::Job* const incoming);
void handleCertificateDeleted(const QKeychain::Job* const incoming);
void handleMnemonicDeleted(const QKeychain::Job* const incoming);
void handlePublicKeyDeleted(const QKeychain::Job* const incoming);
void handlePrivateKeyDeleted(const QKeychain::Job* incoming);
void handleCertificateDeleted(const QKeychain::Job* incoming);
void handleMnemonicDeleted(const QKeychain::Job* incoming);
void handlePublicKeyDeleted(const QKeychain::Job* incoming);
void checkAllSensitiveDataDeleted();

void getPrivateKeyFromServer();
Expand All @@ -350,7 +350,7 @@
void writePrivateKey();
void writeCertificate();

void completeHardwareTokenInitialization(QWidget *settingsDialog);

Check warning on line 353 in src/libsync/clientsideencryption.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKYsSuFLwgU57bpH&open=AZ9rsKYsSuFLwgU57bpH&pullRequest=10286

void setMnemonic(const QString &mnemonic);

Expand Down
2 changes: 2 additions & 0 deletions src/libsync/clientsideencryptionjobs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
req.setHeader(QNetworkRequest::ContentTypeHeader, QByteArrayLiteral("application/x-www-form-urlencoded"));

if (_account->capabilities().clientSideEncryptionVersion() >= 2.0) {
if (!_signature.isEmpty()) {

Check warning on line 164 in src/libsync/clientsideencryptionjobs.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this "if" statement with the enclosing one.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKV3SuFLwgU57bos&open=AZ9rsKV3SuFLwgU57bos&pullRequest=10286
req.setRawHeader(e2eeSignatureHeaderName, _signature);
}
}
Expand Down Expand Up @@ -369,7 +369,9 @@
const auto obj = json.object().toVariantMap();
const auto token = obj["ocs"].toMap()["data"].toMap()["e2e-token"].toByteArray();

#if defined NEXTCLOUD_DEV && NEXTCLOUD_DEV && defined QT_DEBUG
qCDebug(lcCseJob()) << "lock folder finished with code" << retCode << " for:" << path() << " for fileId: " << _fileId << " token:" << token;
#endif

if (!_account->e2e()->getPublicKey().isNull()) {
const auto folderTokenEncrypted = EncryptionHelper::encryptStringAsymmetric(_account->e2e()->getCertificateInformation(), _account->e2e()->paddingMode(), *_account->e2e(), token);
Expand All @@ -385,7 +387,7 @@
return true;
}

void LockEncryptFolderApiJob::setCounter(quint64 counter)

Check warning on line 390 in src/libsync/clientsideencryptionjobs.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "counter" of type "unsigned long long" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKV3SuFLwgU57boy&open=AZ9rsKV3SuFLwgU57boy&pullRequest=10286
{
_counter = counter;
}
Expand Down
3 changes: 3 additions & 0 deletions src/libsync/discovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
constexpr const char *editorNamesForDelayedUpload[] = {"PowerPDF"};
constexpr const char *fileExtensionsToCheckIfOpenForSigning[] = {".pdf"};
constexpr auto delayIntervalForSyncRetryForOpenedForSigningFilesSeconds = 60;
constexpr auto delayIntervalForSyncRetryForFilesExceedQuotaSeconds = 60;

Check warning on line 34 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this identifier to be shorter or equal to 31 characters.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdISuFLwgU57bpd&open=AZ9rsKdISuFLwgU57bpd&pullRequest=10286
}

namespace OCC {
Expand Down Expand Up @@ -771,6 +771,9 @@
result = serverEntry.e2eMangledName.mid(rootPath.length());
return result;
}();
item->_e2eFileEncryptionKey = serverEntry._e2eFileEncryptionKey;
item->_initializationVector = serverEntry._initializationVector;
item->_authenticationTag = serverEntry._authenticationTag;
item->_locked = serverEntry.locked;
item->_lockOwnerDisplayName = serverEntry.lockOwnerDisplayName;
item->_lockOwnerId = serverEntry.lockOwnerId;
Expand Down Expand Up @@ -1869,7 +1872,7 @@
if (_discoveryData->_syncOptions._vfs && _discoveryData->_syncOptions._vfs->mode() != OCC::Vfs::Off &&
(item->_type == CSyncEnums::ItemTypeFile || item->_type == CSyncEnums::ItemTypeDirectory) &&
item->_instruction == CSyncEnums::CSYNC_INSTRUCTION_NONE &&
FileSystem::isLnkFile((_discoveryData->_localDir + path._local)) &&

Check warning on line 1875 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove these redundant parentheses.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdISuFLwgU57bp9&open=AZ9rsKdISuFLwgU57bp9&pullRequest=10286
!_discoveryData->_syncOptions._vfs->isPlaceHolderInSync(_discoveryData->_localDir + path._local)) {
item->_instruction = CSyncEnums::CSYNC_INSTRUCTION_SYNC;
item->_direction = SyncFileItem::Down;
Expand Down Expand Up @@ -2370,7 +2373,7 @@
void ProcessDirectoryJob::startAsyncLocalQuery()
{
QString localPath = _discoveryData->_localDir + _currentFolder._local;
auto localJob = new DiscoverySingleLocalDirectoryJob(_discoveryData->_account, localPath, _discoveryData->_syncOptions._vfs.data(), _discoveryData->_fileSystemReliablePermissions);

Check warning on line 2376 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "localJob" of type "class OCC::DiscoverySingleLocalDirectoryJob *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdISuFLwgU57bqE&open=AZ9rsKdISuFLwgU57bqE&pullRequest=10286

_discoveryData->_currentlyActiveJobs++;
_pendingAsyncJobs++;
Expand Down Expand Up @@ -2458,13 +2461,13 @@
}
}

bool ProcessDirectoryJob::maybeRenameForWindowsCompatibility(const QString &absoluteFileName,

Check warning on line 2464 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function should be declared "const".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdISuFLwgU57bqH&open=AZ9rsKdISuFLwgU57bqH&pullRequest=10286
CSYNC_EXCLUDE_TYPE excludeReason)
{
auto result = true;

const auto leadingAndTrailingSpacesFilesAllowed = !_discoveryData->_shouldEnforceWindowsFileNameCompatibility || _discoveryData->_leadingAndTrailingSpacesFilesAllowed.contains(absoluteFileName);
if (leadingAndTrailingSpacesFilesAllowed) {

Check warning on line 2470 in src/libsync/discovery.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the init-statement to declare "leadingAndTrailingSpacesFilesAllowed" inside the if statement.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdISuFLwgU57bqF&open=AZ9rsKdISuFLwgU57bqF&pullRequest=10286
return result;
}

Expand Down
3 changes: 3 additions & 0 deletions src/libsync/discoveryphase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@

// it is not too big, put it in the white list (so we will not do more query for the children) and and do not block.
const auto sanitisedPath = Utility::trailingSlashPath(path);
_selectiveSyncWhiteList.insert(std::upper_bound(_selectiveSyncWhiteList.begin(), _selectiveSyncWhiteList.end(), sanitisedPath), sanitisedPath);

Check warning on line 123 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace with the version of "std::ranges::upper_bound" that takes a range.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnV&open=AZ9rsKSGSuFLwgU57bnV&pullRequest=10286
return callback(false);
});
}
Expand Down Expand Up @@ -150,7 +150,7 @@
QString adjustRenamedPath(const QMap<QString, QString> &renamedItems, const QString &original)
{
int slashPos = original.size();
while ((slashPos = original.lastIndexOf('/', slashPos - 1)) > 0) {

Check warning on line 153 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

implicit conversion loses integer precision: 'qsizetype' (aka 'long long') to 'int'

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnQ&open=AZ9rsKSGSuFLwgU57bnQ&pullRequest=10286
auto it = renamedItems.constFind(original.left(slashPos));
if (it != renamedItems.constEnd()) {
return *it + original.mid(slashPos);
Expand Down Expand Up @@ -329,7 +329,7 @@

DiscoverySingleLocalDirectoryJob::DiscoverySingleLocalDirectoryJob(const AccountPtr &account,
const QString &localPath,
OCC::Vfs *vfs,

Check warning on line 332 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "vfs" of type "class OCC::Vfs *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnX&open=AZ9rsKSGSuFLwgU57bnX&pullRequest=10286
bool fileSystemReliablePermissions,
QObject *parent)
: QObject{parent}
Expand Down Expand Up @@ -441,7 +441,7 @@
void DiscoverySingleDirectoryJob::start()
{
// Start the actual HTTP job
auto *lsColJob = new LsColJob(_account, _subPath);

Check warning on line 444 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "lsColJob" of type "class OCC::LsColJob *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnd&open=AZ9rsKSGSuFLwgU57bnd&pullRequest=10286

const auto props = LsColJob::defaultProperties(_isRootPath ? LsColJob::FolderType::RootFolder : LsColJob::FolderType::ChildFolder,
_account);
Expand Down Expand Up @@ -640,7 +640,7 @@
// hence, we need to find its path and pass to any subfolder's metadata, so it will fetch the top level metadata when needed
// see https://github.com/nextcloud/end_to_end_encryption_rfc/blob/v2.1/RFC.md
QString topLevelFolderPath = u"/"_s;
for (const QString &topLevelPath : std::as_const(_topLevelE2eeFolderPaths)) {

Check warning on line 643 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reduce the number of nested "break" statements from 2 to 1 authorized.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnk&open=AZ9rsKSGSuFLwgU57bnk&pullRequest=10286
if (_subPath == topLevelPath) {
topLevelFolderPath = u"/"_s;
break;
Expand All @@ -660,7 +660,7 @@
case FolderMetadata::MetadataVersion::Version1_2:
break;
case FolderMetadata::MetadataVersion::Version2_0:
case FolderMetadata::MetadataVersion::Version2_1:

Check warning on line 663 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Reduce this switch case number of lines from 8 to at most 5, for example by extracting code into methods.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnl&open=AZ9rsKSGSuFLwgU57bnl&pullRequest=10286
if (job->signature().isEmpty()) {
qCDebug(lcDiscovery) << "Initial signature is empty.";
_account->reportClientStatus(OCC::ClientStatusReportingStatus::E2EeError_GeneralError);
Expand All @@ -676,7 +676,7 @@
const auto folderType = _topLevelE2eeFolderPaths.contains(_subPath) ? FolderMetadata::FolderType::Root : FolderMetadata::FolderType::Nested;
Q_ASSERT((folderType == FolderMetadata::FolderType::Root) == (rootEncryptedFolderInfo.path == QStringLiteral("/")));

const auto e2EeFolderMetadata = new FolderMetadata(_account,

Check failure on line 679 in src/libsync/discoveryphase.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace the use of "new" with an operation that automatically manages the memory.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSGSuFLwgU57bnn&open=AZ9rsKSGSuFLwgU57bnn&pullRequest=10286
_remoteRootFolderPath,
jsonMetadata,
rootEncryptedFolderInfo,
Expand Down Expand Up @@ -717,6 +717,9 @@
result._isE2eEncrypted = true;
result.e2eMangledName = _subPath.mid(1) + u'/' + result.name;
result.name = encryptedFileInfo->originalFilename;
result._e2eFileEncryptionKey = encryptedFileInfo->encryptionKey;
result._initializationVector = encryptedFileInfo->initializationVector;
result._authenticationTag = encryptedFileInfo->authenticationTag;
}
return result;
});
Expand Down
8 changes: 8 additions & 0 deletions src/libsync/encryptedfoldermetadatahandler.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
Expand Down Expand Up @@ -133,11 +133,11 @@
}

// normally, we should allow locking any nested folder to update its metadata, yet, with the new V2 architecture, this is something we might want to disallow
/*if (!folderMetadata()->isRootEncryptedFolder()) {
qCWarning(lcFetchAndUploadE2eeFolderMetadataJob) << "Error locking folder" << _folderId << "as it is not a top level folder";
emit uploadFinished(-1, tr("Error locking folder."));
return false;
}*/

Check warning on line 140 in src/libsync/encryptedfoldermetadatahandler.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSwSuFLwgU57bnu&open=AZ9rsKSwSuFLwgU57bnu&pullRequest=10286
return true;
}

Expand All @@ -162,9 +162,11 @@
emit fetchFinished(errorCode, reply->errorString());
}

void EncryptedFolderMetadataHandler::slotMetadataReceived(const QJsonDocument &json, int statusCode)

Check warning on line 165 in src/libsync/encryptedfoldermetadatahandler.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "statusCode" of type "int" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKSwSuFLwgU57bn1&open=AZ9rsKSwSuFLwgU57bn1&pullRequest=10286
{
#if defined NEXTCLOUD_DEV && NEXTCLOUD_DEV && defined QT_DEBUG
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Metadata Received, parsing it and decrypting" << json.toVariant();
#endif

const auto job = qobject_cast<GetMetadataApiJob *>(sender());
Q_ASSERT(job);
Expand Down Expand Up @@ -277,6 +279,12 @@
unlockJob->start();
}

void EncryptedFolderMetadataHandler::repairMetadata(const QList<FolderMetadata::DatabaseEncryptedFile> &childItems,
OwncloudPropagator *propagator)
{
_folderMetadata->repair(childItems, propagator);
}

void EncryptedFolderMetadataHandler::startUploadMetadata()
{
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Metadata created, sending to the server.";
Expand Down
14 changes: 10 additions & 4 deletions src/libsync/encryptedfoldermetadatahandler.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/*
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: GPL-2.0-or-later
*/

Check warning on line 4 in src/libsync/encryptedfoldermetadatahandler.h

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Edit this comment to use the C++ format, i.e. "//".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ9rsKdhSuFLwgU57bqN&open=AZ9rsKdhSuFLwgU57bqN&pullRequest=10286

#pragma once

#include "owncloudlib.h"

Check failure on line 8 in src/libsync/encryptedfoldermetadatahandler.h

View workflow job for this annotation

GitHub Actions / build

src/libsync/encryptedfoldermetadatahandler.h:8:10 [clang-diagnostic-error]

'owncloudlib.h' file not found

#include "account.h"
#include "rootencryptedfolderinfo.h"
#include "common/syncjournaldb.h"
#include "foldermetadata.h"

#include <QHash>
#include <QMutex>
Expand All @@ -19,8 +20,10 @@
#include <QPointer>

namespace OCC {
class FolderMetadata;

class SyncJournalDb;
class OwncloudPropagator;

// all metadata operations with server must be performed via this class
class OWNCLOUDSYNC_EXPORT EncryptedFolderMetadataHandler
: public QObject
Expand All @@ -30,19 +33,20 @@
public:
enum class FetchMode {
NonEmptyMetadata = 0,
AllowEmptyMetadata
AllowEmptyMetadata,
AllowBrokenSignature,
};
Q_ENUM(FetchMode);

enum class UploadMode {
DoNotKeepLock = 0,
KeepLock
KeepLock,
};
Q_ENUM(UploadMode);

enum class UnlockFolderWithResult {
Success = 0,
Failure
Failure,
};
Q_ENUM(UnlockFolderWithResult);

Expand All @@ -66,6 +70,8 @@
void fetchMetadata(const FetchMode fetchMode = FetchMode::NonEmptyMetadata);
void uploadMetadata(const UploadMode uploadMode = UploadMode::DoNotKeepLock);
void unlockFolder(const UnlockFolderWithResult result = UnlockFolderWithResult::Success);
void repairMetadata(const QList<OCC::FolderMetadata::DatabaseEncryptedFile> &childItems,
OwncloudPropagator *propagator);

private:
void lockFolder();
Expand Down
Loading
Loading