E2EE. Fix root metadata fetching path for non-root remote sync folder. Refactoring. Stabilizing paths.

Signed-off-by: alex-z <blackslayer4@gmail.com>
This commit is contained in:
alex-z 2024-03-09 22:17:27 +01:00 committed by allexzander
parent 747efd4711
commit c5dd2e89a1
28 changed files with 160 additions and 146 deletions

View File

@ -681,6 +681,12 @@ bool Utility::isCaseClashConflictFile(const QString &name)
return bname.contains(QStringLiteral("(case clash from"));
}
QString Utility::leadingSlashPath(const QString &path)
{
static const auto slash = QLatin1Char('/');
return !path.startsWith(slash) ? QString(slash + path) : path;
}
QString Utility::trailingSlashPath(const QString &path)
{
static const auto slash = QLatin1Char('/');
@ -690,13 +696,13 @@ QString Utility::trailingSlashPath(const QString &path)
QString Utility::noLeadingSlashPath(const QString &path)
{
static const auto slash = QLatin1Char('/');
return path.startsWith(slash) ? path.mid(1) : path;
return path.size() > 1 && path.startsWith(slash) ? path.mid(1) : path;
}
QString Utility::noTrailingSlashPath(const QString &path)
{
static const auto slash = QLatin1Char('/');
return path.endsWith(slash) ? path.chopped(1) : path;
return path.size() > 1 && path.endsWith(slash) ? path.chopped(1) : path;
}
QString Utility::fullRemotePathToRemoteSyncRootRelative(const QString &fullRemotePath, const QString &remoteSyncRoot)

View File

@ -266,7 +266,8 @@ namespace Utility {
* @brief Registers the desktop app as a handler for a custom URI to enable local editing
*/
OCSYNC_EXPORT void registerUriHandlerForLocalEditing();
OCSYNC_EXPORT QString leadingSlashPath(const QString &path);
OCSYNC_EXPORT QString trailingSlashPath(const QString &path);
OCSYNC_EXPORT QString noLeadingSlashPath(const QString &path);
OCSYNC_EXPORT QString noTrailingSlashPath(const QString &path);

View File

@ -857,6 +857,9 @@ void ShareModel::slotDeleteE2EeShare(const SharePtr &share) const
return;
}
Q_ASSERT(folder->remotePath() == QStringLiteral("/")
|| Utility::noLeadingSlashPath(share->path()).startsWith(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(folder->remotePath()))));
const auto removeE2eeShareJob = new UpdateE2eeFolderUsersMetadataJob(account,
folder->journalDb(),
folder->remotePath(),

View File

@ -1537,7 +1537,7 @@ void FolderMan::leaveShare(const QString &localFile)
{
const auto localFileNoTrailingSlash = localFile.endsWith('/') ? localFile.chopped(1) : localFile;
if (const auto folder = FolderMan::instance()->folderForPath(localFileNoTrailingSlash)) {
const auto filePathRelative = QString(localFileNoTrailingSlash).remove(folder->path());
const auto filePathRelative = Utility::noLeadingSlashPath(QString(localFileNoTrailingSlash).remove(folder->path()));
SyncJournalFileRecord rec;
if (folder->journalDb()->getFileRecord(filePathRelative, &rec)
@ -1551,8 +1551,7 @@ void FolderMan::leaveShare(const QString &localFile)
folder->journalDb(),
folder->remotePath(),
UpdateE2eeFolderUsersMetadataJob::Remove,
//TODO: Might need to add a slash to "filePathRelative" once the server is working
filePathRelative,
folder->remotePathTrailingSlash() + filePathRelative,
folder->accountState()->account()->davUser());
_removeE2eeShareJob->setParent(this);
_removeE2eeShareJob->start(true);

View File

@ -488,7 +488,7 @@ void ShareManager::createShare(const QString &path,
job->getSharedWithMe();
}
void ShareManager::createE2EeShareJob(const QString &path,
void ShareManager::createE2EeShareJob(const QString &fullRemotePath,
const ShareePtr sharee,
const Share::Permissions permissions,
const QString &password)
@ -506,11 +506,14 @@ void ShareManager::createE2EeShareJob(const QString &path,
return;
}
Q_ASSERT(folder->remotePath() == QStringLiteral("/") ||
Utility::noLeadingSlashPath(fullRemotePath).startsWith(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(folder->remotePath()))));
const auto createE2eeShareJob = new UpdateE2eeFolderUsersMetadataJob(_account,
folder->journalDb(),
folder->remotePath(),
UpdateE2eeFolderUsersMetadataJob::Add,
path,
fullRemotePath,
sharee->shareWith(),
QSslCertificate{},
this);

View File

@ -416,7 +416,7 @@ public:
/**
* Tell the manager to create and start new UpdateE2eeShareMetadataJob job
*
* @param path The path of the share relative to the user folder on the server
* @param fullRemotePath The path of the share relative to the user folder on the server
* @param shareType The type of share (TypeUser, TypeGroup, TypeRemote)
* @param Permissions The share permissions
* @param folderId The id for an E2EE folder
@ -425,7 +425,7 @@ public:
* On success the signal shareCreated is emitted
* In case of a server error the serverError signal is emitted
*/
void createE2EeShareJob(const QString &path,
void createE2EeShareJob(const QString &fullRemotePath,
const ShareePtr sharee,
const Share::Permissions permissions,
const QString &password = "");

View File

@ -550,13 +550,7 @@ void SocketApi::processEncryptRequest(const QString &localFile)
auto path = rec._path;
// Folder records have directory paths in Foo/Bar/ convention...
// But EncryptFolderJob expects directory path Foo/Bar convention
auto choppedPath = path;
if (choppedPath.endsWith('/') && choppedPath != QStringLiteral("/")) {
choppedPath.chop(1);
}
if (choppedPath.startsWith('/') && choppedPath != QStringLiteral("/")) {
choppedPath = choppedPath.mid(1);
}
const auto choppedPath = Utility::noTrailingSlashPath(Utility::noLeadingSlashPath(path));
auto job = new OCC::EncryptFolderJob(account, folder->journalDb(), choppedPath, choppedPath, folder->remotePath(), rec.numericFileId());
job->setParent(this);

View File

@ -57,17 +57,17 @@ void BasePropagateRemoteDeleteEncrypted::storeFirstErrorString(const QString &er
void BasePropagateRemoteDeleteEncrypted::fetchMetadataForPath(const QString &path)
{
qCDebug(ABSTRACT_PROPAGATE_REMOVE_ENCRYPTED) << "Folder is encrypted, let's its metadata.";
_fullFolderRemotePath = _propagator->fullRemotePath(path);
qCDebug(ABSTRACT_PROPAGATE_REMOVE_ENCRYPTED) << "Folder is encrypted, let's fetch its metadata.";
SyncJournalFileRecord rec;
if (!_propagator->_journal->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(_fullFolderRemotePath, _propagator->remotePath()), &rec) || !rec.isValid()) {
if (!_propagator->_journal->getRootE2eFolderRecord(Utility::noLeadingSlashPath(path), &rec) || !rec.isValid()) {
taskFailed();
return;
}
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_propagator->account(),
_fullFolderRemotePath,
_propagator->fullRemotePath(path),
_propagator->remotePath(),
_propagator->_journal,
rec.path()));

View File

@ -2024,10 +2024,11 @@ void ProcessDirectoryJob::chopVirtualFileSuffix(QString &str) const
DiscoverySingleDirectoryJob *ProcessDirectoryJob::startAsyncServerQuery()
{
if (_dirItem && _dirItem->isEncrypted() && _dirItem->_encryptedFileName.isEmpty()) {
_discoveryData->_topLevelE2eeFolderPaths.insert(QLatin1Char('/') + _dirItem->_file);
_discoveryData->_topLevelE2eeFolderPaths.insert(_discoveryData->_remoteFolder + _dirItem->_file);
}
auto serverJob = new DiscoverySingleDirectoryJob(_discoveryData->_account,
_discoveryData->_remoteFolder + _currentFolder._server,
_currentFolder._server,
_discoveryData->_remoteFolder,
_discoveryData->_topLevelE2eeFolderPaths,
this);
if (!_dirItem) {

View File

@ -371,13 +371,16 @@ void DiscoverySingleLocalDirectoryJob::run() {
DiscoverySingleDirectoryJob::DiscoverySingleDirectoryJob(const AccountPtr &account,
const QString &path,
const QString &remoteRootFolderPath,
const QSet<QString> &topLevelE2eeFolderPaths,
QObject *parent)
: QObject(parent)
, _subPath(path)
, _subPath(remoteRootFolderPath + path)
, _remoteRootFolderPath(remoteRootFolderPath)
, _account(account)
, _topLevelE2eeFolderPaths(topLevelE2eeFolderPaths)
{
Q_ASSERT(!_remoteRootFolderPath.isEmpty());
}
void DiscoverySingleDirectoryJob::start()
@ -692,8 +695,9 @@ void DiscoverySingleDirectoryJob::metadataReceived(const QJsonDocument &json, in
}
const auto e2EeFolderMetadata = new FolderMetadata(_account,
_remoteRootFolderPath,
statusCode == 404 ? QByteArray{} : json.toJson(QJsonDocument::Compact),
RootEncryptedFolderInfo(topLevelFolderPath),
RootEncryptedFolderInfo(Utility::fullRemotePathToRemoteSyncRootRelative(topLevelFolderPath, _remoteRootFolderPath)),
job->signature());
connect(e2EeFolderMetadata, &FolderMetadata::setupComplete, this, [this, e2EeFolderMetadata] {
e2EeFolderMetadata->deleteLater();

View File

@ -145,6 +145,7 @@ class DiscoverySingleDirectoryJob : public QObject
public:
explicit DiscoverySingleDirectoryJob(const AccountPtr &account,
const QString &path,
const QString &remoteRootFolderPath,
/* TODO for topLevelE2eeFolderPaths, from review: I still do not get why giving the whole QSet instead of just the parent of the folder we are in
sounds to me like it would be much more efficient to just have the e2ee parent folder that we are
inside*/
@ -179,6 +180,7 @@ private:
QVector<RemoteInfo> _results;
QString _subPath;
QString _remoteRootFolderPath;
QByteArray _firstEtag;
QByteArray _fileId;
QByteArray _localFileId;

View File

@ -32,17 +32,22 @@ Q_LOGGING_CATEGORY(lcFetchAndUploadE2eeFolderMetadataJob, "nextcloud.sync.propag
namespace OCC {
EncryptedFolderMetadataHandler::EncryptedFolderMetadataHandler(const AccountPtr &account,
const QString &folderPath,
const QString &folderFullRemotePath,
const QString &remoteFolderRoot,
SyncJournalDb *const journalDb,
const QString &pathForTopLevelFolder,
QObject *parent)
: QObject(parent)
, _account(account)
, _folderPath(folderPath)
, _journalDb(journalDb)
, _folderFullRemotePath(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(folderFullRemotePath)))
, _remoteFolderRoot(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(remoteFolderRoot)))
{
_rootEncryptedFolderInfo = RootEncryptedFolderInfo(
RootEncryptedFolderInfo::createRootPath(folderPath, pathForTopLevelFolder));
Q_ASSERT(!_remoteFolderRoot.isEmpty());
Q_ASSERT(_remoteFolderRoot == QStringLiteral("/") || _folderFullRemotePath.startsWith(_remoteFolderRoot));
const auto folderRelativePath = Utility::fullRemotePathToRemoteSyncRootRelative(_folderFullRemotePath, _remoteFolderRoot);
_rootEncryptedFolderInfo = RootEncryptedFolderInfo(RootEncryptedFolderInfo::createRootPath(folderRelativePath, pathForTopLevelFolder));
}
void EncryptedFolderMetadataHandler::fetchMetadata(const FetchMode fetchMode)
@ -53,9 +58,22 @@ void EncryptedFolderMetadataHandler::fetchMetadata(const FetchMode fetchMode)
void EncryptedFolderMetadataHandler::fetchMetadata(const RootEncryptedFolderInfo &rootEncryptedFolderInfo, const FetchMode fetchMode)
{
Q_ASSERT(!rootEncryptedFolderInfo.path.isEmpty());
if (rootEncryptedFolderInfo.path.isEmpty()) {
qCWarning(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for" << _folderFullRemotePath << ". Invalid rootEncryptedFolderInfo!";
emit fetchFinished(-1, tr("Error fetching metadata."));
return;
}
_rootEncryptedFolderInfo = rootEncryptedFolderInfo;
if (_rootEncryptedFolderInfo.path.isEmpty()) {
qCWarning(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for" << _folderPath << ". Invalid _rootEncryptedFolderInfo!";
qCWarning(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for" << _folderFullRemotePath << ". Invalid _rootEncryptedFolderInfo!";
emit fetchFinished(-1, tr("Error fetching metadata."));
return;
}
if (_remoteFolderRoot != QStringLiteral("/") && !_folderFullRemotePath.startsWith(_remoteFolderRoot)) {
qCWarning(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for" << _folderFullRemotePath
<< " and remote root" << _remoteFolderRoot << ". Invalid _remoteFolderRoot or _folderFullRemotePath!";
emit fetchFinished(-1, tr("Error fetching metadata."));
return;
}
@ -99,7 +117,7 @@ void EncryptedFolderMetadataHandler::startFetchMetadata()
void EncryptedFolderMetadataHandler::fetchFolderEncryptedId()
{
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Folder is encrypted, let's get the Id from it.";
const auto job = new LsColJob(_account, _folderPath);
const auto job = new LsColJob(_account, _folderFullRemotePath);
job->setProperties({"resourcetype", "http://owncloud.org/ns:fileid"});
connect(job, &LsColJob::directoryListingSubfolders, this, &EncryptedFolderMetadataHandler::slotFolderEncryptedIdReceived);
connect(job, &LsColJob::finishedWithError, this, &EncryptedFolderMetadataHandler::slotFolderEncryptedIdError);
@ -167,17 +185,17 @@ void EncryptedFolderMetadataHandler::slotMetadataReceived(const QJsonDocument &j
if (statusCode != 200 && statusCode != 404) {
// neither successfully fetched, nor a folder without a metadata, fail further logic
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for folder" << _folderPath;
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error fetching metadata for folder" << _folderFullRemotePath;
emit fetchFinished(statusCode, tr("Error fetching metadata."));
return;
}
const auto rawMetadata = statusCode == 404
? QByteArray{} : json.toJson(QJsonDocument::Compact);
const auto metadata(QSharedPointer<FolderMetadata>::create(_account, rawMetadata, _rootEncryptedFolderInfo, job->signature()));
const auto metadata(QSharedPointer<FolderMetadata>::create(_account, _remoteFolderRoot, rawMetadata, _rootEncryptedFolderInfo, job->signature()));
connect(metadata.data(), &FolderMetadata::setupComplete, this, [this, metadata] {
if (!metadata->isValid()) {
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error parsing or decrypting metadata for folder" << _folderPath;
qCDebug(lcFetchAndUploadE2eeFolderMetadataJob) << "Error parsing or decrypting metadata for folder" << _folderFullRemotePath;
emit fetchFinished(-1, tr("Error parsing or decrypting metadata."));
return;
}

View File

@ -50,7 +50,7 @@ public:
};
Q_ENUM(UnlockFolderWithResult);
explicit EncryptedFolderMetadataHandler(const AccountPtr &account, const QString &folderPath, SyncJournalDb *const journalDb, const QString &pathForTopLevelFolder, QObject *parent = nullptr);
explicit EncryptedFolderMetadataHandler(const AccountPtr &account, const QString &folderPath, const QString &remoteFolderRoot, SyncJournalDb *const journalDb, const QString &pathForTopLevelFolder, QObject *parent = nullptr);
[[nodiscard]] QSharedPointer<FolderMetadata> folderMetadata() const;
@ -101,8 +101,9 @@ public: signals:
private:
AccountPtr _account;
QString _folderPath;
QPointer<SyncJournalDb> _journalDb;
QString _folderFullRemotePath;
QString _remoteFolderRoot;
QByteArray _folderId;
QByteArray _folderToken;

View File

@ -37,8 +37,10 @@ EncryptFolderJob::EncryptFolderJob(const AccountPtr &account, SyncJournalDb *jou
{
SyncJournalFileRecord rec;
const auto currentPath = !_pathNonEncrypted.isEmpty() ? _pathNonEncrypted : _path;
const auto currentPathRelative = Utility::fullRemotePathToRemoteSyncRootRelative(currentPath, _remoteSyncRootPath);
const QString fullRemotePath = Utility::trailingSlashPath(Utility::noLeadingSlashPath(_remoteSyncRootPath)) + currentPathRelative;
[[maybe_unused]] const auto result = _journal->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(currentPath, _remoteSyncRootPath), &rec);
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(account, _path, _journal, rec.path()));
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(account, fullRemotePath, _remoteSyncRootPath, _journal, rec.path()));
}
void EncryptFolderJob::slotSetEncryptionFlag()
@ -102,16 +104,18 @@ void EncryptFolderJob::slotEncryptionFlagError(const QByteArray &fileId,
void EncryptFolderJob::uploadMetadata()
{
const auto currentPath = !_pathNonEncrypted.isEmpty() ? _pathNonEncrypted : _path;
const auto currentPathRelative = Utility::fullRemotePathToRemoteSyncRootRelative(currentPath, _remoteSyncRootPath);
SyncJournalFileRecord rec;
if (!_journal->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(currentPath, _remoteSyncRootPath), &rec)) {
if (!_journal->getRootE2eFolderRecord(currentPathRelative, &rec)) {
emit finished(Error, EncryptionStatusEnums::ItemEncryptionStatus::NotEncrypted);
return;
}
const auto emptyMetadata(QSharedPointer<FolderMetadata>::create(
_account,
_remoteSyncRootPath,
QByteArray{},
RootEncryptedFolderInfo(RootEncryptedFolderInfo::createRootPath(currentPath, rec.path())),
RootEncryptedFolderInfo(RootEncryptedFolderInfo::createRootPath(currentPathRelative, rec.path())),
QByteArray{}));
connect(emptyMetadata.data(), &FolderMetadata::setupComplete, this, [this, emptyMetadata] {

View File

@ -60,21 +60,25 @@ bool FolderMetadata::EncryptedFile::isDirectory() const
return mimetype.isEmpty() || mimetype == QByteArrayLiteral("inode/directory") || mimetype == QByteArrayLiteral("httpd/unix-directory");
}
FolderMetadata::FolderMetadata(AccountPtr account, FolderType folderType)
: _account(account),
FolderMetadata::FolderMetadata(AccountPtr account, const QString &remoteFolderRoot, FolderType folderType) :
_account(account),
_remoteFolderRoot(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(remoteFolderRoot))),
_isRootEncryptedFolder(folderType == FolderType::Root)
{
Q_ASSERT(!_remoteFolderRoot.isEmpty());
qCInfo(lcCseMetadata()) << "Setting up an Empty Metadata";
initEmptyMetadata();
}
FolderMetadata::FolderMetadata(AccountPtr account,
const QString &remoteFolderRoot,
const QByteArray &metadata,
const RootEncryptedFolderInfo &rootEncryptedFolderInfo,
const QByteArray &signature,
QObject *parent)
: QObject(parent)
, _account(account)
, _remoteFolderRoot(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(remoteFolderRoot)))
, _initialMetadata(metadata)
, _isRootEncryptedFolder(rootEncryptedFolderInfo.path == QStringLiteral("/"))
, _metadataKeyForEncryption(rootEncryptedFolderInfo.keyForEncryption)
@ -82,6 +86,7 @@ FolderMetadata::FolderMetadata(AccountPtr account,
, _keyChecksums(rootEncryptedFolderInfo.keyChecksums)
, _initialSignature(signature)
{
Q_ASSERT(!_remoteFolderRoot.isEmpty());
setupVersionFromExistingMetadata(metadata);
const auto doc = QJsonDocument::fromJson(metadata);
@ -987,7 +992,8 @@ bool FolderMetadata::moveFromFileDropToFiles()
void FolderMetadata::startFetchRootE2eeFolderMetadata(const QString &path)
{
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_account, path, nullptr, "/"));
Q_ASSERT(!_remoteFolderRoot.isEmpty());
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_account, Utility::trailingSlashPath(_remoteFolderRoot) + path, _remoteFolderRoot, nullptr, "/"));
connect(_encryptedFolderMetadataHandler.data(),
&EncryptedFolderMetadataHandler::fetchFinished,

View File

@ -93,13 +93,14 @@ public:
};
Q_ENUM(FolderType)
FolderMetadata(AccountPtr account, FolderType folderType = FolderType::Nested);
FolderMetadata(AccountPtr account, const QString &remoteFolderRoot, FolderType folderType = FolderType::Nested);
/*
* construct metadata based on RootEncryptedFolderInfo
* as per E2EE V2, the encryption key and users that have access are only stored in root(top-level) encrypted folder's metadata
* see: https://github.com/nextcloud/end_to_end_encryption_rfc/blob/v2.1/RFC.md
*/
FolderMetadata(AccountPtr account,
const QString &remoteFolderRoot,
const QByteArray &metadata,
const RootEncryptedFolderInfo &rootEncryptedFolderInfo,
const QByteArray &signature,
@ -197,6 +198,7 @@ signals:
private:
AccountPtr _account;
QString _remoteFolderRoot;
QByteArray _initialMetadata;
bool _isRootEncryptedFolder = false;

View File

@ -15,14 +15,7 @@ PropagateDownloadEncrypted::PropagateDownloadEncrypted(OwncloudPropagator *propa
, _item(item)
, _info(_item->_file)
{
const auto rootPath = [=]() {
const auto result = _propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
return result;
}
}();
const auto rootPath = Utility::noLeadingSlashPath(_propagator->remotePath());
const auto remoteFilename = _item->_encryptedFileName.isEmpty() ? _item->_file : _item->_encryptedFileName;
const auto remotePath = QString(rootPath + remoteFilename);
const auto remoteParentPath = remotePath.left(remotePath.lastIndexOf('/'));
@ -42,8 +35,7 @@ void PropagateDownloadEncrypted::start()
emit failed();
return;
}
_encryptedFolderMetadataHandler.reset(
new EncryptedFolderMetadataHandler(_propagator->account(), _remoteParentPath, _propagator->_journal, rec.path()));
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_propagator->account(), _remoteParentPath, _propagator->remotePath(), _propagator->_journal, rec.path()));
connect(_encryptedFolderMetadataHandler.data(),
&EncryptedFolderMetadataHandler::fetchFinished,

View File

@ -20,27 +20,13 @@ Q_LOGGING_CATEGORY(lcPropagateUploadEncrypted, "nextcloud.sync.propagator.upload
PropagateUploadEncrypted::PropagateUploadEncrypted(OwncloudPropagator *propagator, const QString &remoteParentPath, SyncFileItemPtr item, QObject *parent)
: QObject(parent)
, _propagator(propagator)
, _remoteParentPath(remoteParentPath)
, _remoteParentPath(Utility::noLeadingSlashPath(remoteParentPath))
, _item(item)
{
const auto rootPath = [=]() {
const auto result = _propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
return result;
}
}();
_remoteParentAbsolutePath = [=] {
auto path = QString(rootPath + _remoteParentPath);
if (path.endsWith('/')) {
path.chop(1);
}
return path;
}();
const auto rootPath = Utility::trailingSlashPath(Utility::noLeadingSlashPath(_propagator->remotePath()));
_remoteParentAbsolutePath = Utility::noTrailingSlashPath(rootPath + _remoteParentPath);
}
void PropagateUploadEncrypted::start()
{
/* If the file is in a encrypted folder, which we know, we wouldn't be here otherwise,
@ -63,6 +49,7 @@ void PropagateUploadEncrypted::start()
}
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_propagator->account(),
_remoteParentAbsolutePath,
_propagator->remotePath(),
_propagator->_journal,
rec.path()));
@ -143,7 +130,7 @@ void PropagateUploadEncrypted::slotFetchMetadataJobFinished(int statusCode, cons
encryptedFile.initializationVector = EncryptionHelper::generateRandom(16);
_item->_encryptedFileName = _remoteParentPath + QLatin1Char('/') + encryptedFile.encryptedFilename;
_item->_encryptedFileName = Utility::trailingSlashPath(_remoteParentPath) + encryptedFile.encryptedFilename;
_item->_e2eEncryptionStatusRemote = metadata->existingMetadataEncryptionStatus();
_item->_e2eEncryptionServerCapability =
EncryptionStatusEnums::fromEndToEndEncryptionApiVersion(_propagator->account()->capabilities().clientSideEncryptionVersion());
@ -193,8 +180,8 @@ void PropagateUploadEncrypted::slotUploadMetadataFinished(int statusCode, const
qCDebug(lcPropagateUploadEncrypted) << "Encrypted Info:" << outputInfo.path() << outputInfo.fileName() << outputInfo.size();
qCDebug(lcPropagateUploadEncrypted) << "Finalizing the upload part, now the actuall uploader will take over";
emit finalized(outputInfo.path() + QLatin1Char('/') + outputInfo.fileName(),
_remoteParentPath + QLatin1Char('/') + outputInfo.fileName(),
emit finalized(Utility::trailingSlashPath(outputInfo.path()) + outputInfo.fileName(),
Utility::trailingSlashPath(_remoteParentPath) + outputInfo.fileName(),
outputInfo.size());
}

View File

@ -32,8 +32,9 @@ namespace OCC {
UpdateE2eeFolderMetadataJob::UpdateE2eeFolderMetadataJob(OwncloudPropagator *propagator, const SyncFileItemPtr &item, const QString &encryptedRemotePath)
: PropagatorJob(propagator),
_item(item),
_encryptedRemotePath(encryptedRemotePath)
_encryptedRemotePath(Utility::noLeadingSlashPath(propagator->fullRemotePath(encryptedRemotePath)))
{
Q_ASSERT(propagator->remotePath() == QStringLiteral("/") || _encryptedRemotePath.startsWith(Utility::noLeadingSlashPath(propagator->remotePath())));
}
void UpdateE2eeFolderMetadataJob::start()
@ -47,7 +48,7 @@ void UpdateE2eeFolderMetadataJob::start()
return;
}
_encryptedFolderMetadataHandler.reset(
new EncryptedFolderMetadataHandler(propagator()->account(), _encryptedRemotePath, propagator()->_journal, rec.path()));
new EncryptedFolderMetadataHandler(propagator()->account(), _encryptedRemotePath, propagator()->remotePath() , propagator()->_journal, rec.path()));
connect(_encryptedFolderMetadataHandler.data(), &EncryptedFolderMetadataHandler::fetchFinished,
this, &UpdateE2eeFolderMetadataJob::slotFetchMetadataJobFinished);

View File

@ -28,28 +28,26 @@ UpdateE2eeFolderUsersMetadataJob::UpdateE2eeFolderUsersMetadataJob(const Account
SyncJournalDb *journalDb,
const QString &syncFolderRemotePath,
const Operation operation,
const QString &path,
const QString &fullRemotePath,
const QString &folderUserId,
const QSslCertificate &certificate,
QObject *parent)
: QObject(parent)
, _account(account)
, _journalDb(journalDb)
, _syncFolderRemotePath(syncFolderRemotePath)
, _syncFolderRemotePath(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(syncFolderRemotePath)))
, _operation(operation)
, _path(path)
, _fullRemotePath(Utility::noLeadingSlashPath(fullRemotePath))
, _folderUserId(folderUserId)
, _folderUserCertificate(certificate)
{
const auto pathSanitized = _path.startsWith(QLatin1Char('/')) ? _path.mid(1) : _path;
const auto folderPath = _syncFolderRemotePath + pathSanitized;
Q_ASSERT(_syncFolderRemotePath == QStringLiteral("/") || _fullRemotePath.startsWith(_syncFolderRemotePath));
SyncJournalFileRecord rec;
if (!_journalDb->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(_path, _syncFolderRemotePath), &rec) || !rec.isValid()) {
qCDebug(lcUpdateE2eeFolderUsersMetadataJob) << "Could not get root E2ee folder recort for path" << _path;
if (!_journalDb->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(_fullRemotePath, _syncFolderRemotePath), &rec) || !rec.isValid()) {
qCDebug(lcUpdateE2eeFolderUsersMetadataJob) << "Could not get root E2ee folder recort for path" << _fullRemotePath;
return;
}
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_account, folderPath, _journalDb, rec.path()));
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_account, _fullRemotePath, _syncFolderRemotePath, _journalDb, rec.path()));
}
void UpdateE2eeFolderUsersMetadataJob::start(const bool keepLock)
@ -57,7 +55,7 @@ void UpdateE2eeFolderUsersMetadataJob::start(const bool keepLock)
qCWarning(lcUpdateE2eeFolderUsersMetadataJob) << "[DEBUG_LEAVE_SHARE]: UpdateE2eeFolderUsersMetadataJob::start";
if (!_encryptedFolderMetadataHandler) {
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
@ -68,7 +66,7 @@ void UpdateE2eeFolderUsersMetadataJob::start(const bool keepLock)
}
_keepLock = keepLock;
if (_operation != Operation::Add && _operation != Operation::Remove && _operation != Operation::ReEncrypt) {
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
@ -93,15 +91,14 @@ void UpdateE2eeFolderUsersMetadataJob::slotStartE2eeMetadataJobs()
return;
}
const auto pathSanitized = _path.startsWith(QLatin1Char('/')) ? _path.mid(1) : _path;
const auto folderPath = _syncFolderRemotePath + pathSanitized;
const auto folderPathRelative = Utility::fullRemotePathToRemoteSyncRootRelative(_fullRemotePath, _syncFolderRemotePath);
SyncJournalFileRecord rec;
if (!_journalDb->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(_path, _syncFolderRemotePath), &rec) || !rec.isValid()) {
emit finished(404, tr("Could not find root encrypted folder for folder %1").arg(_path));
if (!_journalDb->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(folderPathRelative, _syncFolderRemotePath), &rec) || !rec.isValid()) {
emit finished(404, tr("Could not find root encrypted folder for folder %1").arg(_fullRemotePath));
return;
}
const auto rootEncFolderInfo = RootEncryptedFolderInfo(RootEncryptedFolderInfo::createRootPath(folderPath, rec.path()), _metadataKeyForEncryption, _metadataKeyForDecryption, _keyChecksums);
const auto rootEncFolderInfo = RootEncryptedFolderInfo(RootEncryptedFolderInfo::createRootPath(folderPathRelative, rec.path()), _metadataKeyForEncryption, _metadataKeyForDecryption, _keyChecksums);
connect(_encryptedFolderMetadataHandler.data(), &EncryptedFolderMetadataHandler::fetchFinished,
this, &UpdateE2eeFolderUsersMetadataJob::slotFetchMetadataJobFinished);
_encryptedFolderMetadataHandler->fetchMetadata(rootEncFolderInfo, EncryptedFolderMetadataHandler::FetchMode::AllowEmptyMetadata);
@ -113,12 +110,12 @@ void UpdateE2eeFolderUsersMetadataJob::slotFetchMetadataJobFinished(int statusCo
if (statusCode != 200) {
qCritical(lcUpdateE2eeFolderUsersMetadataJob) << "fetch metadata finished with error" << statusCode << message;
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
if (!_encryptedFolderMetadataHandler->folderMetadata() || !_encryptedFolderMetadataHandler->folderMetadata()->isValid()) {
emit finished(403, tr("Could not add or remove a folder user %1, for folder %2").arg(_folderUserId).arg(_path));
emit finished(403, tr("Could not add or remove a folder user %1, for folder %2").arg(_folderUserId).arg(_fullRemotePath));
return;
}
startUpdate();
@ -128,14 +125,14 @@ void UpdateE2eeFolderUsersMetadataJob::startUpdate()
{
if (_operation == Operation::Invalid) {
qCDebug(lcUpdateE2eeFolderUsersMetadataJob) << "Invalid operation";
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
if (_operation == Operation::Add || _operation == Operation::Remove) {
if (!_encryptedFolderMetadataHandler->folderMetadata()) {
qCDebug(lcUpdateE2eeFolderUsersMetadataJob) << "Metadata is null";
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
@ -145,7 +142,7 @@ void UpdateE2eeFolderUsersMetadataJob::startUpdate()
if (!result) {
qCDebug(lcUpdateE2eeFolderUsersMetadataJob) << "Could not perform operation" << _operation << "on metadata";
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
return;
}
@ -166,7 +163,7 @@ void UpdateE2eeFolderUsersMetadataJob::slotUpdateMetadataFinished(int code, cons
qCDebug(lcUpdateE2eeFolderUsersMetadataJob()) << "Unlocking the folder.";
unlockFolder(EncryptedFolderMetadataHandler::UnlockFolderWithResult::Failure);
} else {
emit finished(code, tr("Error updating metadata for a folder %1").arg(_path) + QStringLiteral(":%1").arg(message));
emit finished(code, tr("Error updating metadata for a folder %1").arg(_fullRemotePath) + QStringLiteral(":%1").arg(message));
}
return;
}
@ -198,16 +195,16 @@ void UpdateE2eeFolderUsersMetadataJob::scheduleSubJobs()
unlockFolder(EncryptedFolderMetadataHandler::UnlockFolderWithResult::Failure);
} else {
qCWarning(lcUpdateE2eeFolderUsersMetadataJob()) << "Metadata is invalid.";
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath));
}
return;
}
const auto pathInDb = _path.mid(_syncFolderRemotePath.size());
const auto pathInDb = Utility::fullRemotePathToRemoteSyncRootRelative(_fullRemotePath, _syncFolderRemotePath);
[[maybe_unused]] const auto result = _journalDb->getFilesBelowPath(pathInDb.toUtf8(), [this](const SyncJournalFileRecord &record) {
if (record.isDirectory()) {
const auto folderMetadata = _encryptedFolderMetadataHandler->folderMetadata();
const auto subJob = new UpdateE2eeFolderUsersMetadataJob(_account, _journalDb, _syncFolderRemotePath, UpdateE2eeFolderUsersMetadataJob::ReEncrypt, QString::fromUtf8(record._e2eMangledName));
const auto subJob = new UpdateE2eeFolderUsersMetadataJob(_account, _journalDb, _syncFolderRemotePath, UpdateE2eeFolderUsersMetadataJob::ReEncrypt, Utility::trailingSlashPath(_syncFolderRemotePath) + QString::fromUtf8(record._e2eMangledName));
subJob->setMetadataKeyForEncryption(folderMetadata->metadataKeyForEncryption());
subJob->setMetadataKeyForDecryption(folderMetadata->metadataKeyForDecryption());
subJob->setKeyChecksums(folderMetadata->keyChecksums());
@ -257,7 +254,7 @@ void UpdateE2eeFolderUsersMetadataJob::slotSubJobFinished(int code, const QStrin
Q_ASSERT(job);
if (!job) {
qCWarning(lcUpdateE2eeFolderUsersMetadataJob) << "slotSubJobFinished must be invoked by signal";
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_path) + QStringLiteral(":%1").arg(message));
emit finished(-1, tr("Error updating metadata for a folder %1").arg(_fullRemotePath) + QStringLiteral(":%1").arg(message));
subJobsFinished(false);
return;
}
@ -346,7 +343,7 @@ void UpdateE2eeFolderUsersMetadataJob::setSubJobSyncItems(const QHash<QString, S
const QString &UpdateE2eeFolderUsersMetadataJob::path() const
{
return _path;
return _fullRemotePath;
}
const UpdateE2eeFolderUsersMetadataJob::UserData &UpdateE2eeFolderUsersMetadataJob::userData() const

View File

@ -42,7 +42,7 @@ public:
QString password;
};
explicit UpdateE2eeFolderUsersMetadataJob(const AccountPtr &account, SyncJournalDb *journalDb,const QString &syncFolderRemotePath, const Operation operation, const QString &path = {}, const QString &folderUserId = {}, const QSslCertificate &certificate = QSslCertificate{}, QObject *parent = nullptr);
explicit UpdateE2eeFolderUsersMetadataJob(const AccountPtr &account, SyncJournalDb *journalDb,const QString &syncFolderRemotePath, const Operation operation, const QString &fullRemotePath = {}, const QString &folderUserId = {}, const QSslCertificate &certificate = QSslCertificate{}, QObject *parent = nullptr);
~UpdateE2eeFolderUsersMetadataJob() override = default;
public:
@ -91,7 +91,7 @@ private:
QPointer<SyncJournalDb> _journalDb;
QString _syncFolderRemotePath;
Operation _operation = Invalid;
QString _path;
QString _fullRemotePath;
QString _folderUserId;
QSslCertificate _folderUserCertificate;
QByteArray _folderToken;

View File

@ -30,13 +30,14 @@ namespace OCC {
UpdateMigratedE2eeMetadataJob::UpdateMigratedE2eeMetadataJob(OwncloudPropagator *propagator,
const SyncFileItemPtr &syncFileItem,
const QString &path,
const QString &fullRemotePath,
const QString &folderRemotePath)
: PropagatorJob(propagator)
, _item(syncFileItem)
, _path(path)
, _folderRemotePath(folderRemotePath)
, _fullRemotePath(fullRemotePath)
, _folderRemotePath(Utility::noLeadingSlashPath(Utility::noTrailingSlashPath(folderRemotePath)))
{
Q_ASSERT(_fullRemotePath == QStringLiteral("/") || _fullRemotePath.startsWith(_folderRemotePath));
}
void UpdateMigratedE2eeMetadataJob::start()
@ -45,7 +46,7 @@ void UpdateMigratedE2eeMetadataJob::start()
propagator()->_journal,
_folderRemotePath,
UpdateE2eeFolderUsersMetadataJob::Add,
_path,
_fullRemotePath,
propagator()->account()->davUser(),
propagator()->account()->e2e()->_certificate);
updateMedatadaAndSubfoldersJob->setParent(this);
@ -83,9 +84,9 @@ PropagatorJob::JobParallelism UpdateMigratedE2eeMetadataJob::parallelism() const
return PropagatorJob::JobParallelism::WaitForFinished;
}
QString UpdateMigratedE2eeMetadataJob::path() const
QString UpdateMigratedE2eeMetadataJob::fullRemotePath() const
{
return _path;
return _fullRemotePath;
}
void UpdateMigratedE2eeMetadataJob::addSubJobItem(const QString &key, const SyncFileItemPtr &syncFileItem)

View File

@ -33,7 +33,7 @@ public:
[[nodiscard]] JobParallelism parallelism() const override;
[[nodiscard]] QString path() const;
[[nodiscard]] QString fullRemotePath() const;
void addSubJobItem(const QString &key, const SyncFileItemPtr &syncFileItem);
@ -43,7 +43,7 @@ private slots:
private:
SyncFileItemPtr _item;
QHash<QString, SyncFileItemPtr> _subJobItems;
QString _path;
QString _fullRemotePath;
QString _folderRemotePath;
};

View File

@ -43,14 +43,14 @@ void OCC::HydrationJob::setAccount(const AccountPtr &account)
_account = account;
}
QString OCC::HydrationJob::remotePath() const
QString OCC::HydrationJob::remoteSyncRootPath() const
{
return _remotePath;
return _remoteSyncRootPath;
}
void OCC::HydrationJob::setRemotePath(const QString &remotePath)
void OCC::HydrationJob::setRemoteSyncRootPath(const QString &path)
{
_remotePath = remotePath;
_remoteSyncRootPath = Utility::noLeadingSlashPath(path);
}
QString OCC::HydrationJob::localPath() const
@ -137,10 +137,10 @@ void OCC::HydrationJob::start()
{
Q_ASSERT(_account);
Q_ASSERT(_journal);
Q_ASSERT(!_remotePath.isEmpty() && !_localPath.isEmpty());
Q_ASSERT(!_remoteSyncRootPath.isEmpty() && !_localPath.isEmpty());
Q_ASSERT(!_requestId.isEmpty() && !_folderPath.isEmpty());
Q_ASSERT(_remotePath.endsWith('/'));
Q_ASSERT(_remoteSyncRootPath.endsWith('/'));
Q_ASSERT(_localPath.endsWith('/'));
Q_ASSERT(!_folderPath.startsWith('/'));
@ -305,7 +305,7 @@ void OCC::HydrationJob::slotFetchMetadataJobFinished(int statusCode, const QStri
if (encryptedFileExactName == file.encryptedFilename) {
qCDebug(lcHydration) << "Found matching encrypted metadata for file, starting download" << _requestId << _folderPath;
_transferDataSocket = _transferDataServer->nextPendingConnection();
_job = new GETEncryptedFileJob(_account, _remotePath + e2eMangledName(), _transferDataSocket, {}, {}, 0, file, this);
_job = new GETEncryptedFileJob(_account, Utility::trailingSlashPath(_remoteSyncRootPath) + e2eMangledName(), _transferDataSocket, {}, {}, 0, file, this);
connect(qobject_cast<GETEncryptedFileJob *>(_job), &GETEncryptedFileJob::finishedSignal, this, &HydrationJob::onGetFinished);
_job->start();
@ -347,7 +347,7 @@ void OCC::HydrationJob::handleNewConnection()
{
qCInfo(lcHydration) << "Got new connection starting GETFileJob" << _requestId << _folderPath;
_transferDataSocket = _transferDataServer->nextPendingConnection();
_job = new GETFileJob(_account, _remotePath + _folderPath, _transferDataSocket, {}, {}, 0, this);
_job = new GETFileJob(_account, Utility::trailingSlashPath(_remoteSyncRootPath) + _folderPath, _transferDataSocket, {}, {}, 0, this);
connect(_job, &GETFileJob::finishedSignal, this, &HydrationJob::onGetFinished);
_job->start();
}
@ -356,25 +356,17 @@ void OCC::HydrationJob::handleNewConnectionForEncryptedFile()
{
// TODO: the following code is borrowed from PropagateDownloadEncrypted (should we factor it out and reuse? YES! Should we do it now? Probably not, as, this would imply modifying PropagateDownloadEncrypted, so we need a separate PR)
qCInfo(lcHydration) << "Got new connection for encrypted file. Getting required info for decryption...";
const auto rootPath = [=]() {
const auto result = _remotePath;
if (result.startsWith('/')) {
return result.mid(1);
} else {
return result;
}
}();
const auto remoteFilename = e2eMangledName();
const auto remotePath = QString(rootPath + remoteFilename);
const auto _remoteParentPath = remotePath.left(remotePath.lastIndexOf('/'));
const QString fullRemotePath = Utility::trailingSlashPath(_remoteSyncRootPath) + remoteFilename;
const auto containingFolderFullRemotePath = fullRemotePath.left(fullRemotePath.lastIndexOf('/'));
SyncJournalFileRecord rec;
if (!_journal->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(_remoteParentPath, rootPath), &rec) || !rec.isValid()) {
if (!_journal->getRootE2eFolderRecord(Utility::fullRemotePathToRemoteSyncRootRelative(containingFolderFullRemotePath, _remoteSyncRootPath), &rec) || !rec.isValid()) {
emitFinished(Error);
return;
}
_encryptedFolderMetadataHandler.reset(new EncryptedFolderMetadataHandler(_account, _remoteParentPath, _journal, rec.path()));
_encryptedFolderMetadataHandler.reset(
new EncryptedFolderMetadataHandler(_account, containingFolderFullRemotePath, _remoteSyncRootPath, _journal, rec.path()));
connect(_encryptedFolderMetadataHandler.data(),
&EncryptedFolderMetadataHandler::fetchFinished,
this,

View File

@ -46,8 +46,8 @@ public:
AccountPtr account() const;
void setAccount(const AccountPtr &account);
QString remotePath() const;
void setRemotePath(const QString &remotePath);
[[nodiscard]] QString remoteSyncRootPath() const;
void setRemoteSyncRootPath(const QString &path);
QString localPath() const;
void setLocalPath(const QString &localPath);
@ -99,7 +99,7 @@ private:
void startServerAndWaitForConnections();
AccountPtr _account;
QString _remotePath;
QString _remoteSyncRootPath;
QString _localPath;
SyncJournalDb *_journal = nullptr;
bool _isCancelled = false;

View File

@ -445,7 +445,7 @@ void VfsCfApi::scheduleHydrationJob(const QString &requestId, const QString &fol
auto job = new HydrationJob(this);
job->setAccount(params().account);
job->setRemotePath(params().remotePath);
job->setRemoteSyncRootPath(params().remotePath);
job->setLocalPath(params().filesystemPath);
job->setJournal(params().journal);
job->setRequestId(requestId);

View File

@ -96,7 +96,7 @@ private slots:
void testInitializeNewRootFolderMetadataThenEncryptAndDecrypt()
{
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, FolderMetadata::FolderType::Root));
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, "/", FolderMetadata::FolderType::Root));
QSignalSpy metadataSetupCompleteSpy(metadata.data(), &FolderMetadata::setupComplete);
metadataSetupCompleteSpy.wait();
QCOMPARE(metadataSetupCompleteSpy.count(), 1);
@ -178,7 +178,7 @@ private slots:
QJsonDocument ocsDoc = QJsonDocument::fromJson(QStringLiteral("{\"ocs\": {\"data\": {\"meta-data\": \"%1\"}}}").arg(QString::fromUtf8(encryptedMetadataCopy)).toUtf8());
QScopedPointer<FolderMetadata> metadataFromJson(new FolderMetadata(_account,
QScopedPointer<FolderMetadata> metadataFromJson(new FolderMetadata(_account, "/",
ocsDoc.toJson(),
RootEncryptedFolderInfo::makeDefault(), signature));
QSignalSpy metadataSetupExistingCompleteSpy(metadataFromJson.data(), &FolderMetadata::setupComplete);
@ -190,7 +190,7 @@ private slots:
void testE2EeFolderMetadataSharing()
{
// instantiate empty metadata, add a file, and share with a second user "sharee"
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, FolderMetadata::FolderType::Root));
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, "/", FolderMetadata::FolderType::Root));
QSignalSpy metadataSetupCompleteSpy(metadata.data(), &FolderMetadata::setupComplete);
metadataSetupCompleteSpy.wait();
QCOMPARE(metadataSetupCompleteSpy.count(), 1);
@ -280,7 +280,7 @@ private slots:
QJsonDocument ocsDoc =
QJsonDocument::fromJson(QStringLiteral("{\"ocs\": {\"data\": {\"meta-data\": \"%1\"}}}").arg(QString::fromUtf8(encryptedMetadataCopy)).toUtf8());
QScopedPointer<FolderMetadata> metadataFromJsonForSecondUser(new FolderMetadata(_secondAccount, ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
QScopedPointer<FolderMetadata> metadataFromJsonForSecondUser(new FolderMetadata(_secondAccount, "/", ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
QSignalSpy metadataSetupExistingCompleteSpy(metadataFromJsonForSecondUser.data(), &FolderMetadata::setupComplete);
metadataSetupExistingCompleteSpy.wait();
QCOMPARE(metadataSetupExistingCompleteSpy.count(), 1);
@ -303,7 +303,7 @@ private slots:
QJsonDocument ocsDocFromSecondUser = QJsonDocument::fromJson(
QStringLiteral("{\"ocs\": {\"data\": {\"meta-data\": \"%1\"}}}").arg(QString::fromUtf8(encryptedMetadataFromSecondUser)).toUtf8());
QScopedPointer<FolderMetadata> metadataFromJsonForFirstUserToCheckCrossSharing(new FolderMetadata(_account,
QScopedPointer<FolderMetadata> metadataFromJsonForFirstUserToCheckCrossSharing(new FolderMetadata(_account, "/",
ocsDocFromSecondUser.toJson(),
RootEncryptedFolderInfo::makeDefault(),
signatureAfterSecondUserModification));

View File

@ -79,7 +79,7 @@ private slots:
_account->e2e()->_publicKey = publicKey;
_account->e2e()->_privateKey = privateKey;
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, FolderMetadata::FolderType::Root));
QScopedPointer<FolderMetadata> metadata(new FolderMetadata(_account, "/", FolderMetadata::FolderType::Root));
QSignalSpy metadataSetupCompleteSpy(metadata.data(), &FolderMetadata::setupComplete);
metadataSetupCompleteSpy.wait();
QCOMPARE(metadataSetupCompleteSpy.count(), 1);
@ -146,7 +146,7 @@ private slots:
const auto signature = metadata->metadataSignature();
QJsonDocument ocsDoc =
QJsonDocument::fromJson(QStringLiteral("{\"ocs\": {\"data\": {\"meta-data\": \"%1\"}}}").arg(QString::fromUtf8(encryptedMetadata)).toUtf8());
_parsedMetadataWithFileDrop.reset(new FolderMetadata(_account, ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
_parsedMetadataWithFileDrop.reset(new FolderMetadata(_account, "/", ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
QSignalSpy metadataWithFileDropSetupCompleteSpy(_parsedMetadataWithFileDrop.data(), &FolderMetadata::setupComplete);
metadataWithFileDropSetupCompleteSpy.wait();
@ -167,7 +167,7 @@ private slots:
QJsonDocument ocsDoc =
QJsonDocument::fromJson(QStringLiteral("{\"ocs\": {\"data\": {\"meta-data\": \"%1\"}}}").arg(QString::fromUtf8(encryptedMetadata)).toUtf8());
_parsedMetadataAfterProcessingFileDrop.reset(new FolderMetadata(_account, ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
_parsedMetadataAfterProcessingFileDrop.reset(new FolderMetadata(_account, "/", ocsDoc.toJson(), RootEncryptedFolderInfo::makeDefault(), signature));
QSignalSpy metadataAfterProcessingFileDropSetupCompleteSpy(_parsedMetadataAfterProcessingFileDrop.data(), &FolderMetadata::setupComplete);
metadataAfterProcessingFileDropSetupCompleteSpy.wait();