Merge pull request #8384 from nextcloud/bugfix/noDownloadShareFixes

fix(permissions): decode share "no download" permission
This commit is contained in:
Matthieu Gallien 2025-07-01 18:35:53 +02:00 committed by GitHub
commit ba62717c95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 159 additions and 105 deletions

View File

@ -8,8 +8,13 @@
#include <QVariant>
#include <QLoggingCategory>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonValue>
#include <QJsonObject>
#include <cstring>
#include <type_traits>
namespace OCC {
@ -67,8 +72,42 @@ RemotePermissions RemotePermissions::internalFromServerString(const QString &val
const T&otherProperties,
MountedPermissionAlgorithm algorithm)
{
constexpr auto shareAttributesDecoder = [] (const auto &shareAttributes, RemotePermissions &perm) -> void {
auto missingDownloadPermission = false;
const auto &jsonArray = shareAttributes.array();
for (const auto &oneEntry : jsonArray) {
const auto &jsonObject = oneEntry.toObject();
if (jsonObject.contains(u"scope") && jsonObject.value(u"scope").toString() == u"permissions") {
if (jsonObject.contains(u"key") && jsonObject.value(u"key").toString() == u"download") {
if (jsonObject.contains(u"value") && !jsonObject.value(u"value").toBool()) {
missingDownloadPermission = true;
}
break;
}
}
}
if (missingDownloadPermission) {
perm.unsetPermission(RemotePermissions::CanRead);
}
};
RemotePermissions perm;
perm.fromArray(value.utf16());
Q_ASSERT(perm.hasPermission(RemotePermissions::CanRead));
if (otherProperties.contains(QStringLiteral("share-attributes"))) {
const auto shareAttributesRawValue = otherProperties.value(QStringLiteral("share-attributes"));
if constexpr (std::is_same<T, QMap<QString, QString>>::value) {
const auto &shareAttributes = QJsonDocument::fromJson(otherProperties.value(QStringLiteral("share-attributes")).toUtf8());
shareAttributesDecoder(shareAttributes, perm);
} else if constexpr (std::is_same<T, QVariantMap>::value) {
const auto &shareAttributes = QJsonDocument::fromJson(otherProperties.value(QStringLiteral("share-attributes")).toString().toUtf8());
shareAttributesDecoder(shareAttributes, perm);
}
}
if (algorithm == MountedPermissionAlgorithm::WildGuessMountedSubProperty) {
return perm;

View File

@ -826,6 +826,9 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it
item->_direction = SyncFileItem::Down;
item->_instruction = CSYNC_INSTRUCTION_SYNC;
item->_type = ItemTypeVirtualFileDownload;
} else if (serverEntry.isValid() && !serverEntry.isDirectory && !serverEntry.remotePerm.isNull() && !serverEntry.remotePerm.hasPermission(RemotePermissions::CanRead)) {
item->_instruction = CSYNC_INSTRUCTION_REMOVE;
item->_direction = SyncFileItem::Down;
} else if (dbEntry._etag != serverEntry.etag) {
item->_direction = SyncFileItem::Down;
item->_modtime = serverEntry.modtime;
@ -851,9 +854,6 @@ void ProcessDirectoryJob::processFileAnalyzeRemoteInfo(const SyncFileItemPtr &it
item->_modtime = serverEntry.modtime;
item->_size = sizeOnServer;
item->_instruction = CSYNC_INSTRUCTION_UPDATE_METADATA;
} else if (serverEntry.isValid() && !serverEntry.isDirectory && !serverEntry.remotePerm.isNull() && !serverEntry.remotePerm.hasPermission(RemotePermissions::CanRead)) {
item->_instruction = CSYNC_INSTRUCTION_REMOVE;
item->_direction = SyncFileItem::Down;
} else if (dbEntry._remotePerm != serverEntry.remotePerm || dbEntry._fileId != serverEntry.fileId || metaDataSizeNeedsUpdateForE2EeFilePlaceholder) {
if (metaDataSizeNeedsUpdateForE2EeFilePlaceholder) {
// we are updating placeholder sizes after migrating from older versions with VFS + E2EE implicit hydration not supported

View File

@ -418,7 +418,8 @@ void DiscoverySingleDirectoryJob::start()
<< "http://owncloud.org/ns:permissions"
<< "http://owncloud.org/ns:checksums"
<< "http://nextcloud.org/ns:is-encrypted"
<< "http://nextcloud.org/ns:metadata-files-live-photo";
<< "http://nextcloud.org/ns:metadata-files-live-photo"
<< "http://nextcloud.org/ns:share-attributes";
if (_isRootPath)
props << "http://owncloud.org/ns:data-fingerprint";
@ -593,7 +594,7 @@ void DiscoverySingleDirectoryJob::directoryListingIteratedSlot(const QString &fi
// The first entry is for the folder itself, we should process it differently.
_ignoredFirst = true;
if (map.contains("permissions")) {
auto perm = RemotePermissions::fromServerString(map.value("permissions"),
const auto perm = RemotePermissions::fromServerString(map.value("permissions"),
_account->serverHasMountRootProperty() ? RemotePermissions::MountedPermissionAlgorithm::UseMountRootProperty : RemotePermissions::MountedPermissionAlgorithm::WildGuessMountedSubProperty,
map);
emit firstDirectoryPermissions(perm);

View File

@ -412,6 +412,13 @@ FakePropfindReply::FakePropfindReply(FileInfo &remoteRootFileInfo, QNetworkAcces
xml.writeTextElement(ocUri, QStringLiteral("quota-available-bytes"), std::to_string(fileInfo.quota.bytesAvailable));
xml.writeTextElement(ocUri, QStringLiteral("quota-used-bytes"), std::to_string(fileInfo.quota.bytesUsed));
xml.writeTextElement(ocUri, QStringLiteral("permissions"), !fileInfo.permissions.isNull() ? QString(fileInfo.permissions.toString()) : fileInfo.isShared ? QStringLiteral("GSRDNVCKW") : QStringLiteral("GRDNVCKW"));
if (fileInfo.isShared) {
if (fileInfo.downloadForbidden) {
xml.writeTextElement(ocUri, QStringLiteral("share-attributes"), QStringLiteral("[{\"scope\":\"permissions\",\"key\":\"download\",\"value\":false}]"));
} else {
xml.writeTextElement(ocUri, QStringLiteral("share-attributes"), QStringLiteral("[{\"scope\":\"permissions\",\"key\":\"download\",\"value\":true}]"));
}
}
xml.writeTextElement(ocUri, QStringLiteral("share-permissions"), QString::number(static_cast<int>(OCC::SharePermissions(OCC::SharePermissionRead |
OCC::SharePermissionUpdate |
OCC::SharePermissionCreate |

View File

@ -177,6 +177,7 @@ public:
int operationStatus = 200;
bool isDir = true;
bool isShared = false;
bool downloadForbidden = false;
OCC::RemotePermissions permissions; // When uset, defaults to everything
QDateTime lastModified = QDateTime::currentDateTimeUtc().addDays(-7);
QByteArray etag = generateEtag();

View File

@ -136,13 +136,13 @@ private slots:
};
//put them in some directories
fakeFolder.remoteModifier().mkdir("normalDirectory_PERM_CKDNV_");
insertIn("normalDirectory_PERM_CKDNV_/");
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_" );
insertIn("readonlyDirectory_PERM_M_/" );
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_/subdir_PERM_CK_");
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_");
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data", 100);
fakeFolder.remoteModifier().mkdir("normalDirectory_PERM_CKDNVG_");
insertIn("normalDirectory_PERM_CKDNVG_/");
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_MG_" );
insertIn("readonlyDirectory_PERM_MG_/" );
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_");
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_");
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data", 100);
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
@ -213,13 +213,13 @@ private slots:
//1. remove the file than cannot be removed
// (they should be recovered)
fakeFolder.localModifier().remove("normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_GWVN_.data");
removeReadOnly("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_GWVN_.data");
fakeFolder.localModifier().remove("normalDirectory_PERM_CKDNVG_/cannotBeRemoved_PERM_GWVN_.data");
removeReadOnly("readonlyDirectory_PERM_MG_/cannotBeRemoved_PERM_GWVN_.data");
//2. remove the file that can be removed
// (they should properly be gone)
removeReadOnly("normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_GD_.data");
removeReadOnly("readonlyDirectory_PERM_M_/canBeRemoved_PERM_GD_.data");
removeReadOnly("normalDirectory_PERM_CKDNVG_/canBeRemoved_PERM_GD_.data");
removeReadOnly("readonlyDirectory_PERM_MG_/canBeRemoved_PERM_GD_.data");
//3. Edit the files that cannot be modified
// (they should be recovered, and a conflict shall be created)
@ -228,19 +228,19 @@ private slots:
QFile(fakeFolder.localPath() + file).setPermissions(QFile::WriteOwner | QFile::ReadOwner);
fakeFolder.localModifier().appendByte(file);
};
editReadOnly("normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_GDVN_.data");
editReadOnly("normalDirectory_PERM_CKDNVG_/cannotBeModified_PERM_GDVN_.data");
#if !defined Q_OS_WINDOWS
editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data");
editReadOnly("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data");
#endif
//4. Edit other files
// (they should be uploaded)
fakeFolder.localModifier().appendByte("normalDirectory_PERM_CKDNV_/canBeModified_PERM_GW_.data");
fakeFolder.localModifier().appendByte("readonlyDirectory_PERM_M_/canBeModified_PERM_GW_.data");
fakeFolder.localModifier().appendByte("normalDirectory_PERM_CKDNVG_/canBeModified_PERM_GW_.data");
fakeFolder.localModifier().appendByte("readonlyDirectory_PERM_MG_/canBeModified_PERM_GW_.data");
//5. Create a new file in a read write folder
// (should be uploaded)
fakeFolder.localModifier().insert("normalDirectory_PERM_CKDNV_/newFile_PERM_GWDNV_.data", 106 );
fakeFolder.localModifier().insert("normalDirectory_PERM_CKDNVG_/newFile_PERM_GWDNV_.data", 106 );
applyPermissionsFromName(fakeFolder.remoteModifier());
//do the sync
@ -250,26 +250,26 @@ private slots:
//1.
// File should be recovered
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/cannotBeRemoved_PERM_GWVN_.data"));
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNVG_/cannotBeRemoved_PERM_GWVN_.data"));
#if !defined Q_OS_WINDOWS
QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data")->size, cannotBeModifiedSize);
QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data")->size, cannotBeModifiedSize);
#endif
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_GWVN_.data"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/cannotBeRemoved_PERM_GWVN_.data"));
//2.
// File should be deleted
QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNV_/canBeRemoved_PERM_GD_.data"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/canBeRemoved_PERM_GD_.data"));
QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNVG_/canBeRemoved_PERM_GD_.data"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/canBeRemoved_PERM_GD_.data"));
//3.
// File should be recovered
QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_GDVN_.data")->size, cannotBeModifiedSize);
QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNVG_/cannotBeModified_PERM_GDVN_.data")->size, cannotBeModifiedSize);
// and conflict created
auto c1 = findConflict(currentLocalState, "normalDirectory_PERM_CKDNV_/cannotBeModified_PERM_GDVN_.data");
auto c1 = findConflict(currentLocalState, "normalDirectory_PERM_CKDNVG_/cannotBeModified_PERM_GDVN_.data");
QVERIFY(c1);
QCOMPARE(c1->size, cannotBeModifiedSize + 1);
#if !defined Q_OS_WINDOWS
auto c2 = findConflict(currentLocalState, "readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data");
auto c2 = findConflict(currentLocalState, "readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data");
QVERIFY(c2);
QCOMPARE(c2->size, cannotBeModifiedSize + 1);
#endif
@ -280,12 +280,12 @@ private slots:
#endif
//4. File should be updated, that's tested by assertLocalAndRemoteDir
QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNV_/canBeModified_PERM_GW_.data")->size, canBeModifiedSize + 1);
QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_M_/canBeModified_PERM_GW_.data")->size, canBeModifiedSize + 1);
QCOMPARE(currentLocalState.find("normalDirectory_PERM_CKDNVG_/canBeModified_PERM_GW_.data")->size, canBeModifiedSize + 1);
QCOMPARE(currentLocalState.find("readonlyDirectory_PERM_MG_/canBeModified_PERM_GW_.data")->size, canBeModifiedSize + 1);
//5.
// the file should be in the server and local
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/newFile_PERM_GWDNV_.data"));
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNVG_/newFile_PERM_GWDNV_.data"));
// Both side should still be the same
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -294,7 +294,7 @@ private slots:
//6. Create a new file in a read only folder
// (they should not be uploaded)
insertReadOnly("readonlyDirectory_PERM_M_/newFile_PERM_GWDNV_.data", 105 );
insertReadOnly("readonlyDirectory_PERM_MG_/newFile_PERM_GWDNV_.data", 105 );
applyPermissionsFromName(fakeFolder.remoteModifier());
// error: can't upload to readonly
@ -305,8 +305,8 @@ private slots:
//6.
// The file should not exist on the remote, and not be there
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/newFile_PERM_GWDNV_.data"));
QVERIFY(!fakeFolder.currentRemoteState().find("readonlyDirectory_PERM_M_/newFile_PERM_GWDNV_.data"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/newFile_PERM_GWDNV_.data"));
QVERIFY(!fakeFolder.currentRemoteState().find("readonlyDirectory_PERM_MG_/newFile_PERM_GWDNV_.data"));
// Both side should still be the same
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -314,15 +314,15 @@ private slots:
//######################################################################
qInfo( "remove the read only directory" );
// -> It must be recovered
removeReadOnly("readonlyDirectory_PERM_M_");
removeReadOnly("readonlyDirectory_PERM_MG_");
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
assertCsyncJournalOk(fakeFolder.syncJournal());
currentLocalState = fakeFolder.currentLocalState();
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/cannotBeRemoved_PERM_GWVN_.data"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/cannotBeRemoved_PERM_GWVN_.data"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_"));
// the subdirectory had delete permissions, but, it was within the recovered directory, so must also get recovered
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
applyPermissionsFromName(fakeFolder.remoteModifier());
@ -335,25 +335,25 @@ private slots:
//Missing directory should be restored
//new directory should be uploaded
renameReadOnly("readonlyDirectory_PERM_M_/subdir_PERM_CK_", "normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_");
renameReadOnly("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_", "normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_");
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
currentLocalState = fakeFolder.currentLocalState();
// old name restored
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_"));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_"));
// contents moved (had move permissions)
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data"));
// new still exist (and is uploaded)
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data"));
QVERIFY(currentLocalState.find("normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data"));
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
// restore for further tests
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_");
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data");
fakeFolder.remoteModifier().mkdir("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_");
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data");
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -367,15 +367,15 @@ private slots:
QVERIFY(fakeFolder.syncOnce());
assertCsyncJournalOk(fakeFolder.syncJournal());
QVERIFY(fakeFolder.currentLocalState().find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data" ));
QVERIFY(fakeFolder.currentLocalState().find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data" ));
//1. rename a directory in a read only folder
//Missing directory should be restored
//new directory should stay but not be uploaded
renameReadOnly("readonlyDirectory_PERM_M_/subdir_PERM_CK_", "readonlyDirectory_PERM_M_/newname_PERM_CK_" );
renameReadOnly("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_", "readonlyDirectory_PERM_MG_/newname_PERM_CK_" );
//2. move a directory from read to read only (move the directory from previous step)
renameReadOnly("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_", "readonlyDirectory_PERM_M_/moved_PERM_CK_" );
renameReadOnly("normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_", "readonlyDirectory_PERM_MG_/moved_PERM_CK_" );
// can't upload to readonly but not an error
QVERIFY(fakeFolder.syncOnce());
@ -383,24 +383,24 @@ private slots:
//1.
// old name restored
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_" ));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_" ));
// including contents
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_M_/subdir_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data" ));
QVERIFY(currentLocalState.find("readonlyDirectory_PERM_MG_/subdir_PERM_CKG_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data" ));
// new no longer exists
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/newname_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data" ));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/newname_PERM_CK_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data" ));
// but is not on server: should have been locally removed
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/newname_PERM_CK_"));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/newname_PERM_CK_"));
//2.
// old removed
QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_"));
QVERIFY(!currentLocalState.find("normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_"));
// but still on the server: the rename causing an error meant the deletes didn't execute
QVERIFY(fakeFolder.currentRemoteState().find("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_"));
QVERIFY(fakeFolder.currentRemoteState().find("normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_"));
// new no longer exists
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/moved_PERM_CK_/subsubdir_PERM_CKDNV_/normalFile_PERM_GWVND_.data" ));
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/moved_PERM_CK_/subsubdir_PERM_CKDNVG_/normalFile_PERM_GWVND_.data" ));
// should have been cleaned up as invalid item inside read-only folder
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_M_/moved_PERM_CK_"));
fakeFolder.remoteModifier().remove("normalDirectory_PERM_CKDNV_/subdir_PERM_CKDNV_");
QVERIFY(!currentLocalState.find("readonlyDirectory_PERM_MG_/moved_PERM_CK_"));
fakeFolder.remoteModifier().remove("normalDirectory_PERM_CKDNVG_/subdir_PERM_CKDNVG_");
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -408,20 +408,20 @@ private slots:
//######################################################################
qInfo( "multiple restores of a file create different conflict files" );
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data");
fakeFolder.remoteModifier().insert("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data");
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data");
fakeFolder.localModifier().setContents("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data", 's');
editReadOnly("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data");
fakeFolder.localModifier().setContents("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data", 's');
//do the sync
applyPermissionsFromName(fakeFolder.remoteModifier());
QVERIFY(fakeFolder.syncOnce());
assertCsyncJournalOk(fakeFolder.syncJournal());
QThread::sleep(1); // make sure changes have different mtime
editReadOnly("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data");
fakeFolder.localModifier().setContents("readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data", 'd');
editReadOnly("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data");
fakeFolder.localModifier().setContents("readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data", 'd');
//do the sync
applyPermissionsFromName(fakeFolder.remoteModifier());
@ -431,7 +431,7 @@ private slots:
// there should be two conflict files
currentLocalState = fakeFolder.currentLocalState();
int count = 0;
while (auto i = findConflict(currentLocalState, "readonlyDirectory_PERM_M_/cannotBeModified_PERM_GDVN_.data")) {
while (auto i = findConflict(currentLocalState, "readonlyDirectory_PERM_MG_/cannotBeModified_PERM_GDVN_.data")) {
QVERIFY((i->contentChar == 's') || (i->contentChar == 'd'));
removeReadOnly(i->path());
currentLocalState = fakeFolder.currentLocalState();
@ -580,7 +580,7 @@ private slots:
rm.mkdir("forbidden-move/sub2");
rm.insert("forbidden-move/sub2/file2.txt", 100);
rm.find("forbidden-move")->permissions = RemotePermissions::fromServerString("WNCK");
rm.find("forbidden-move")->permissions = RemotePermissions::fromServerString("WNCKG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -627,7 +627,7 @@ private slots:
remote.mkdir("readOnlyFolder");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("MG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -644,7 +644,7 @@ private slots:
remote.mkdir("readWriteFolder");
remote.find("readWriteFolder")->permissions = RemotePermissions::fromServerString("CKWDNVRSM");
remote.find("readWriteFolder")->permissions = RemotePermissions::fromServerString("GCKWDNVRSM");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -662,21 +662,21 @@ private slots:
remote.mkdir("testFolder");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("MG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QVERIFY(isReadOnlyFolder(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder")).toStdWString()));
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("CKWDNVRSM");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("CKWDNVRSMG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
QVERIFY(!isReadOnlyFolder(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder")).toStdWString()));
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("MG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -692,7 +692,7 @@ private slots:
remote.mkdir("testFolder");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("testFolder")->permissions = RemotePermissions::fromServerString("MG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -700,7 +700,7 @@ private slots:
remote.mkdir("testFolder/subFolderReadWrite");
remote.mkdir("testFolder/subFolderReadOnly");
remote.find("testFolder/subFolderReadOnly")->permissions = RemotePermissions::fromServerString("m");
remote.find("testFolder/subFolderReadOnly")->permissions = RemotePermissions::fromServerString("mG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
@ -709,8 +709,8 @@ private slots:
QVERIFY(!isReadOnlyFolder(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder/subFolderReadWrite")).toStdWString()));
QVERIFY(isReadOnlyFolder(static_cast<QString>(fakeFolder.localPath() + QStringLiteral("/testFolder/subFolderReadOnly")).toStdWString()));
remote.find("testFolder/subFolderReadOnly")->permissions = RemotePermissions::fromServerString("CKWDNVRSm");
remote.find("testFolder/subFolderReadWrite")->permissions = RemotePermissions::fromServerString("m");
remote.find("testFolder/subFolderReadOnly")->permissions = RemotePermissions::fromServerString("CKWDNVRSmG");
remote.find("testFolder/subFolderReadWrite")->permissions = RemotePermissions::fromServerString("mG");
remote.mkdir("testFolder/newSubFolder");
remote.create("testFolder/testFile", 12, '9');
remote.create("testFolder/testReadOnlyFile", 13, '8');
@ -743,8 +743,8 @@ private slots:
remote.mkdir("readOnlyFolder/test");
remote.insert("readOnlyFolder/readOnlyFile.txt");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("MG");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("mG");
remote.find("readOnlyFolder/readOnlyFile.txt")->permissions = RemotePermissions::fromServerString("mG");
QVERIFY(fakeFolder.syncOnce());
@ -773,8 +773,8 @@ private slots:
remote.mkdir("readOnlyFolder/test");
remote.insert("readOnlyFolder/readOnlyFile.txt");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("MG");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("mG");
remote.find("readOnlyFolder/readOnlyFile.txt")->permissions = RemotePermissions::fromServerString("mG");
QVERIFY(fakeFolder.syncOnce());
@ -806,9 +806,9 @@ private slots:
remote.mkdir("readOnlyFolder/test");
remote.insert("readOnlyFolder/readOnlyFile.txt");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("readOnlyFolder/child")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("MG");
remote.find("readOnlyFolder/child")->permissions = RemotePermissions::fromServerString("mG");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("mG");
remote.find("readOnlyFolder/readOnlyFile.txt")->permissions = RemotePermissions::fromServerString("mG");
QVERIFY(fakeFolder.syncOnce());
@ -840,8 +840,8 @@ private slots:
remote.mkdir("readOnlyFolder/test");
remote.insert("readOnlyFolder/readOnlyFile.txt");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("M");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder")->permissions = RemotePermissions::fromServerString("MG");
remote.find("readOnlyFolder/test")->permissions = RemotePermissions::fromServerString("mG");
remote.find("readOnlyFolder/readOnlyFile.txt")->permissions = RemotePermissions::fromServerString("mG");
QVERIFY(fakeFolder.syncOnce());
@ -850,7 +850,7 @@ private slots:
remote.insert("readOnlyFolder/test/newFile.txt");
remote.find("readOnlyFolder/test/newFile.txt")->permissions = RemotePermissions::fromServerString("mG");
remote.mkdir("readOnlyFolder/test/newFolder");
remote.find("readOnlyFolder/test/newFolder")->permissions = RemotePermissions::fromServerString("m");
remote.find("readOnlyFolder/test/newFolder")->permissions = RemotePermissions::fromServerString("mG");
remote.appendByte("readOnlyFolder/readOnlyFile.txt");
QVERIFY(fakeFolder.syncOnce());
@ -884,7 +884,10 @@ private slots:
fakeFolder.remoteModifier().insert("file");
setAllPerm(fakeFolder.remoteModifier().find("file"), RemotePermissions::fromServerString("DNVRS"));
auto fileItem = fakeFolder.remoteModifier().find("file");
Q_ASSERT(fileItem);
fileItem->isShared = true;
fileItem->downloadForbidden = true;
// also hook into discovery!!
SyncFileItemVector discovery;
@ -918,7 +921,10 @@ private slots:
return nullptr;
});
setAllPerm(fileInfo, RemotePermissions::fromServerString("DNVRS"));
auto fileItem = fakeFolder.remoteModifier().find("file", true);
Q_ASSERT(fileItem);
fileItem->isShared = true;
fileItem->downloadForbidden = true;
// also hook into discovery!!
SyncFileItemVector discovery;

View File

@ -2257,19 +2257,19 @@ private slots:
fakeFolder.remoteModifier().insert("file2");
fakeFolder.remoteModifier().insert("file3");
fakeFolder.remoteModifier().find("folder")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("folder")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("folder/file1.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("folder/file2.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("folder/file3.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd/this is a long long long long long long long long long long long long long long long long l.docx - Sh.lnk")->permissions = RemotePermissions::fromServerString("SG");
QVERIFY(fakeFolder.syncOnce());
@ -2299,20 +2299,20 @@ private slots:
fakeFolder.remoteModifier().insert("file2");
fakeFolder.remoteModifier().insert("file3");
fakeFolder.remoteModifier().find("folder")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("folder")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("folder/file1.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("folder/file2.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("folder/file3.lnk")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd")->permissions = RemotePermissions::fromServerString("DNVS");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd")->permissions = RemotePermissions::fromServerString("DNVSG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd")->permissions = RemotePermissions::fromServerString("SG");
fakeFolder.remoteModifier().find("abcdefabcdefabcdefabcdefabcdefabcd/abcdef abcdef abcdef a/abcdef abcdef/abcdef acbdef abcd/123abcdefabcdef1/123123abcdef123 abcdef1/12abcabc/12abcabd/this is a long long long long long long long long long long long long long long long long l.docx - Sh.md")->permissions = RemotePermissions::fromServerString("GS");
QVERIFY(fakeFolder.syncOnce());
@ -2460,7 +2460,7 @@ private slots:
// when subdir folder permissions change, expect the parent to be touched
touchedFiles.clear();
fakeFolder.remoteModifier().find("directory")->permissions = RemotePermissions::fromServerString("S");
fakeFolder.remoteModifier().find("directory")->permissions = RemotePermissions::fromServerString("SG");
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(touchedFiles.size(), 1);
QVERIFY(touchedFiles.contains(fakeFolder.localModifier().find("directory").fileName()));