Repository: nextcloud/desktop (C++)

Issue:
[Bug]: Linux Desktop client does not unlock files
### ⚠️ Before submitting, please verify the following: ⚠️

- [X] This is a **bug**, not a question or a configuration issue.
- [X] This issue is **not** already reported on Github (I've searched it).
- [X] Nextcloud Server and Desktop Client are **up to date**. See [Server Maintenance and Release Schedule](https://github.com/nextcloud/server/wiki/Maintenance-and-Release-Schedule) and [Desktop Releases](https://nextcloud.com/install/#install-clients) for supported versions.
- [X] I agree to follow Nextcloud's [Code of Conduct](https://nextcloud.com/contribute/code-of-conduct/)

### Bug description

In my test cases the linux desktop client does add a lock if a shared file is locked via the web interface or via the desktop integration, but after releasing the lock, the lock on the client still exists. On windows this works in my tests. I also testes to thare a single file instead of a folder, but with the same behavior.

I am running server version "25.0.4 Enterprise" and linux client "3.7.4" on archlinux. The Windows test case is still on "3.6.4" but showing the correct behavior. Unfortunately I cannot update the client, as it is on a terminal server I don't have admin permission on and the client is installed via an AD group policy.

I am not sure if the lock feature is covered by our GEANT subscription, but if it helps I can drop a case into the customer ticket system as well.

### Steps to reproduce

1. Create a shared folder.
2. Lock a file in that folder, either using the web interface to lock or edit a file, or the desktop client.
3. The Lock is added to both windows (+r bit) and linux (-w bit) test accounts.
4. Unlock the file, again via web or desktop.
5. The lock is removed on windows (-r bit), but still is read only on linux.
6. Forcing a sync does not help as well as restarting the desktop client.
7. I can only unlock the file by setting the write bit by hand or by removing the folder from selective sync and resync the whole folder, so the server knows about the unlocked state.

See attached the linux client log.
[client_debug_log_lockfile.zip](https://github.com/nextcloud/desktop/files/11016036/client_debug_log_lockfile.zip)


### Expected behavior

Releasing the lock removes the write lock on both linux and windows.

### Which files are affected by this bug

lock-test.txt

### Operating system

Linux

### Which version of the operating system you are running.

Archlinux

### Package

Distro package manager

### Nextcloud Server version

25.0.4 Enterprise

### Nextcloud Desktop Client version

3.7.4

### Is this bug present after an update or on a fresh install?

Updated to a major version (ex. 3.3.6 to 3.4.0)

### Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

### Are you using an external user-backend?

- [X] Default internal user-backend
- [X] LDAP/ Active Directory
- [ ] SSO - SAML
- [ ] Other

### Nextcloud Server logs

_No response_

### Additional info

_No response_


Discussion: As a follow up - once the file is changed again after unlocking, the unlocked status will be synced correctly. But if the file is only unlocked and never changed again, the file stays locked locally.



Fix (patch):
diff --git a/src/libsync/propagatedownload.cpp b/src/libsync/propagatedownload.cpp
index 2edd3c4c5ba82..08ab484891501 100644
--- a/src/libsync/propagatedownload.cpp
+++ b/src/libsync/propagatedownload.cpp
@@ -1198,8 +1198,15 @@ void PropagateDownloadFile::downloadFinished()
         }
     }
 
-    // Apply the remote permissions
-    FileSystem::setFileReadOnlyWeak(_tmpFile.fileName(), !_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite));
+    if (_item->_locked == SyncFileItem::LockStatus::LockedItem && (_item->_lockOwnerType != SyncFileItem::LockOwnerType::UserLock || _item->_lockOwnerId != propagator()->account()->davUser())) {
+        qCDebug(lcPropagateDownload()) << _tmpFile << "file is locked: making it read only";
+        FileSystem::setFileReadOnly(_tmpFile.fileName(), true);
+    } else {
+        qCDebug(lcPropagateDownload()) << _tmpFile << "file is not locked: making it"
+                                       << ((!_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite)) ? "read only"
+                                                                                                                                            : "read write");
+        FileSystem::setFileReadOnlyWeak(_tmpFile.fileName(), (!_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite)));
+    }
 
     const auto isConflict = (_item->_instruction == CSYNC_INSTRUCTION_CONFLICT
                              && (QFileInfo(filename).isDir() || !FileSystem::fileEquals(filename, _tmpFile.fileName()))) ||
@@ -1262,12 +1269,6 @@ void PropagateDownloadFile::downloadFinished()
         return;
     }
 
-    qCInfo(lcPropagateDownload()) << propagator()->account()->davUser() << propagator()->account()->davDisplayName() << propagator()->account()->displayName();
-    if (_item->_locked == SyncFileItem::LockStatus::LockedItem && (_item->_lockOwnerType != SyncFileItem::LockOwnerType::UserLock || _item->_lockOwnerId != propagator()->account()->davUser())) {
-        qCInfo(lcPropagateDownload()) << "file is locked: making it read only";
-        FileSystem::setFileReadOnly(filename, true);
-    }
-
     FileSystem::setFileHidden(filename, false);
 
     // Maybe we downloaded a newer version of the file than we thought we would...
@@ -1346,6 +1347,14 @@ void PropagateDownloadFile::updateMetadata(bool isConflict)
         handleRecallFile(fn, propagator()->localPath(), *propagator()->_journal);
     }
 
+    if (_item->_locked == SyncFileItem::LockStatus::LockedItem && (_item->_lockOwnerType != SyncFileItem::LockOwnerType::UserLock || _item->_lockOwnerId != propagator()->account()->davUser())) {
+        qCDebug(lcPropagateDownload()) << fn << "file is locked: making it read only";
+        FileSystem::setFileReadOnly(fn, true);
+    } else {
+        qCDebug(lcPropagateDownload()) << fn << "file is not locked: making it" << ((!_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite)) ? "read only" : "read write");
+        FileSystem::setFileReadOnlyWeak(fn, (!_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite)));
+    }
+
     qint64 duration = _stopwatch.elapsed();
     if (isLikelyFinishedQuickly() && duration > 5 * 1000) {
         qCWarning(lcPropagateDownload) << "WARNING: Unexpectedly slow connection, took" << duration << "msec for" << _item->_size - _resumeStart << "bytes for" << _item->_file;