Merge pull request #5978 from nextcloud/bugfix/lockUnlockVirtualFiles

update read-only status of virtual files when needed for lock state
This commit is contained in:
Matthieu Gallien 2023-08-21 16:37:45 +02:00 committed by GitHub
commit 5183455dd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 129 additions and 0 deletions

View File

@ -389,6 +389,18 @@ void OCC::SyncEngine::slotItemDiscovered(const OCC::SyncFileItemPtr &item)
modificationHappened = true;
}
if (item->_type == CSyncEnums::ItemTypeVirtualFile) {
if (item->_locked == SyncFileItem::LockStatus::LockedItem && (item->_lockOwnerType != SyncFileItem::LockOwnerType::UserLock || item->_lockOwnerId != account()->davUser())) {
qCDebug(lcEngine()) << filePath << "file is locked: making it read only";
FileSystem::setFileReadOnly(filePath, true);
} else {
qCDebug(lcEngine()) << filePath << "file is not locked: making it"
<< ((!item->_remotePerm.isNull() && !item->_remotePerm.hasPermission(RemotePermissions::CanWrite)) ? "read only"
: "read write");
FileSystem::setFileReadOnlyWeak(filePath, (!item->_remotePerm.isNull() && !item->_remotePerm.hasPermission(RemotePermissions::CanWrite)));
}
}
// Update on-disk virtual file metadata
if (modificationHappened && item->_type == ItemTypeVirtualFile) {
auto r = _syncOptions._vfs->updateMetadata(filePath, item->_modtime, item->_size, item->_fileId);

View File

@ -631,6 +631,45 @@ private slots:
auto expectedState = fakeFolder.currentLocalState();
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
}
void testLockFile_lockedFileReadOnly_afterSync()
{
FakeFolder fakeFolder{ FileInfo::A12_B12_C12_S12() };
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
ItemCompletedSpy completeSpy(fakeFolder);
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
OCC::SyncJournalFileRecord fileRecordBefore;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordBefore));
QVERIFY(!fileRecordBefore._lockstate._locked);
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
const auto localFileNotLocked = QFileInfo{fakeFolder.localPath() + u"A/a1"};
QVERIFY(localFileNotLocked.isWritable());
fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch(), 1226);
fakeFolder.remoteModifier().setModTimeKeepEtag(QStringLiteral("A/a1"), QDateTime::currentDateTime());
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a1"));
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
OCC::SyncJournalFileRecord fileRecordLocked;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordLocked));
QVERIFY(fileRecordLocked._lockstate._locked);
auto expectedState = fakeFolder.currentLocalState();
QCOMPARE(fakeFolder.currentRemoteState(), expectedState);
const auto localFileLocked = QFileInfo{fakeFolder.localPath() + u"A/a1"};
QVERIFY(!localFileLocked.isWritable());
}
};
QTEST_GUILESS_MAIN(TestLockFile)

View File

@ -1315,6 +1315,45 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testLockFile_lockedFileReadOnly_afterSync()
{
FakeFolder fakeFolder{ FileInfo{} };
setupVfs(fakeFolder);
ItemCompletedSpy completeSpy(fakeFolder);
fakeFolder.remoteModifier().mkdir("A");
fakeFolder.remoteModifier().insert("A/a1");
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
OCC::SyncJournalFileRecord fileRecordBefore;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordBefore));
QVERIFY(fileRecordBefore.isValid());
QVERIFY(!fileRecordBefore._lockstate._locked);
const auto localFileNotLocked = QFileInfo{fakeFolder.localPath() + u"A/a1"};
QVERIFY(localFileNotLocked.isWritable());
fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch(), 1226);
fakeFolder.remoteModifier().setModTimeKeepEtag(QStringLiteral("A/a1"), QDateTime::currentDateTime());
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a1"));
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1"))->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
OCC::SyncJournalFileRecord fileRecordLocked;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1"), &fileRecordLocked));
QVERIFY(fileRecordLocked.isValid());
QVERIFY(fileRecordLocked._lockstate._locked);
const auto localFileLocked = QFileInfo{fakeFolder.localPath() + u"A/a1"};
QVERIFY(!localFileLocked.isWritable());
}
};
QTEST_GUILESS_MAIN(TestSyncCfApi)

View File

@ -1906,6 +1906,45 @@ private slots:
QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState());
}
void testLockFile_lockedFileReadOnly_afterSync()
{
FakeFolder fakeFolder{ FileInfo{} };
setupVfs(fakeFolder);
ItemCompletedSpy completeSpy(fakeFolder);
fakeFolder.remoteModifier().mkdir("A");
fakeFolder.remoteModifier().insert("A/a1");
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1") + DVSUFFIX)->_locked, OCC::SyncFileItem::LockStatus::UnlockedItem);
OCC::SyncJournalFileRecord fileRecordBefore;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1") + DVSUFFIX, &fileRecordBefore));
QVERIFY(fileRecordBefore.isValid());
QVERIFY(!fileRecordBefore._lockstate._locked);
const auto localFileNotLocked = QFileInfo{fakeFolder.localPath() + u"A/a1" + DVSUFFIX};
QVERIFY(localFileNotLocked.isWritable());
fakeFolder.remoteModifier().modifyLockState(QStringLiteral("A/a1"), FileModifier::LockState::FileLocked, 1, QStringLiteral("Nextcloud Office"), {}, QStringLiteral("richdocuments"), QDateTime::currentDateTime().toSecsSinceEpoch(), 1226);
fakeFolder.remoteModifier().setModTimeKeepEtag(QStringLiteral("A/a1"), QDateTime::currentDateTime());
fakeFolder.remoteModifier().appendByte(QStringLiteral("A/a1"));
completeSpy.clear();
QVERIFY(fakeFolder.syncOnce());
QCOMPARE(completeSpy.findItem(QStringLiteral("A/a1") + DVSUFFIX)->_locked, OCC::SyncFileItem::LockStatus::LockedItem);
OCC::SyncJournalFileRecord fileRecordLocked;
QVERIFY(fakeFolder.syncJournal().getFileRecord(QStringLiteral("A/a1") + DVSUFFIX, &fileRecordLocked));
QVERIFY(fileRecordLocked.isValid());
QVERIFY(fileRecordLocked._lockstate._locked);
const auto localFileLocked = QFileInfo{fakeFolder.localPath() + u"A/a1" + DVSUFFIX};
QVERIFY(!localFileLocked.isWritable());
}
};
QTEST_GUILESS_MAIN(TestSyncVirtualFiles)