make folders read-write when needed when deleting local items

if a folder is read-only, when deleting content inside this folder, it
may be needed to make it temporary read-write

do this as required by the automated tests

Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
This commit is contained in:
Matthieu Gallien 2024-08-19 15:04:58 +02:00 committed by Matthieu Gallien
parent abde33e7e5
commit 8dcbdebd02
3 changed files with 49 additions and 4 deletions

View file

@ -480,6 +480,25 @@ bool FileSystem::isFolderReadOnly(const std::filesystem::path &path) noexcept
return false;
}
}
FileSystem::FilePermissionsRestore::FilePermissionsRestore(const QString &path, FolderPermissions temporaryPermissions)
: _path(path)
{
const auto stdStrPath = _path.toStdWString();
_initialPermissions = FileSystem::isFolderReadOnly(stdStrPath) ? OCC::FileSystem::FolderPermissions::ReadOnly : OCC::FileSystem::FolderPermissions::ReadWrite;
if (_initialPermissions != temporaryPermissions) {
_rollbackNeeded = true;
FileSystem::setFolderPermissions(_path, temporaryPermissions);
}
}
FileSystem::FilePermissionsRestore::~FilePermissionsRestore()
{
if (_rollbackNeeded) {
FileSystem::setFolderPermissions(_path, _initialPermissions);
}
}
#endif
} // namespace OCC

View file

@ -41,6 +41,19 @@ class SyncJournal;
* @brief This file contains file system helper
*/
namespace FileSystem {
class OWNCLOUDSYNC_EXPORT FilePermissionsRestore {
public:
explicit FilePermissionsRestore(const QString &path,
FileSystem::FolderPermissions temporaryPermissions);
~FilePermissionsRestore();
private:
QString _path;
FileSystem::FolderPermissions _initialPermissions;
bool _rollbackNeeded = false;
};
struct OWNCLOUDSYNC_EXPORT FileLockingInfo {
enum class Type { Unset = -1, Locked, Unlocked };
QString path;

View file

@ -63,6 +63,9 @@ bool PropagateLocalRemove::removeRecursively(const QString &path)
QStringList errors;
QList<QPair<QString, bool>> deleted;
#if !defined(Q_OS_MACOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15
const auto fileInfo = QFileInfo{absolute};
const auto parentFolderPath = fileInfo.dir().absolutePath();
const auto parentPermissionsHandler = FileSystem::FilePermissionsRestore{parentFolderPath, FileSystem::FolderPermissions::ReadWrite};
FileSystem::setFolderPermissions(absolute, FileSystem::FolderPermissions::ReadWrite);
#endif
bool success = FileSystem::removeRecursively(
@ -126,10 +129,18 @@ void PropagateLocalRemove::start()
return;
}
} else {
if (FileSystem::fileExists(filename)
&& !FileSystem::remove(filename, &removeError)) {
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
return;
if (FileSystem::fileExists(filename)) {
#if !defined(Q_OS_MACOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_15
const auto fileInfo = QFileInfo{filename};
const auto parentFolderPath = fileInfo.dir().absolutePath();
const auto parentPermissionsHandler = FileSystem::FilePermissionsRestore{parentFolderPath, FileSystem::FolderPermissions::ReadWrite};
#endif
if (!FileSystem::remove(filename, &removeError)) {
done(SyncFileItem::NormalError, removeError, ErrorCategory::GenericError);
return;
}
}
}
}
@ -368,6 +379,8 @@ void PropagateLocalRename::start()
};
#endif
const auto folderPermissionsHandler = FileSystem::FilePermissionsRestore{existingFile, FileSystem::FolderPermissions::ReadWrite};
emit propagator()->touchedFile(existingFile);
emit propagator()->touchedFile(targetFile);
if (QString renameError; !FileSystem::rename(existingFile, targetFile, &renameError)) {