diff --git a/src/libsync/discovery.cpp b/src/libsync/discovery.cpp index 0f3776b6b5716..f93c26b0488d4 100644 --- a/src/libsync/discovery.cpp +++ b/src/libsync/discovery.cpp @@ -57,6 +57,7 @@ ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinS ProcessDirectoryJob::ProcessDirectoryJob(const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp, ProcessDirectoryJob *parent) : QObject(parent) , _dirItem(dirItem) + , _dirParentItem(parent->_dirItem) , _lastSyncTimestamp(lastSyncTimestamp) , _queryServer(queryServer) , _queryLocal(queryLocal) @@ -67,9 +68,10 @@ ProcessDirectoryJob::ProcessDirectoryJob(const PathTuple &path, const SyncFileIt computePinState(parent->_pinState); } -ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent) +ProcessDirectoryJob::ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, const SyncFileItemPtr &parentDirItem, QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent) : QObject(parent) , _dirItem(dirItem) + , _dirParentItem(parentDirItem) , _lastSyncTimestamp(lastSyncTimestamp) , _queryLocal(queryLocal) , _discoveryData(data) @@ -1777,6 +1779,9 @@ bool ProcessDirectoryJob::checkPermissions(const OCC::SyncFileItemPtr &item) qCWarning(lcDisco) << "checkForPermission: ERROR" << item->_file; item->_instruction = CSYNC_INSTRUCTION_ERROR; item->_errorString = tr("Not allowed because you don't have permission to add subfolders to that folder"); + const auto localPath = QString{_discoveryData->_localDir + item->_file}; + qCWarning(lcDisco) << "unexpected new folder in a read-only folder will be made read-write" << localPath; + FileSystem::setFolderPermissions(localPath, FileSystem::FolderPermissions::ReadWrite); return false; } else if (!item->isDirectory() && !perms.hasPermission(RemotePermissions::CanAddFile)) { qCWarning(lcDisco) << "checkForPermission: ERROR" << item->_file; @@ -1968,6 +1973,21 @@ int ProcessDirectoryJob::processSubJobs(int nbJobs) if (_childModified && _dirItem->_instruction == CSYNC_INSTRUCTION_REMOVE) { // re-create directory that has modified contents _dirItem->_instruction = CSYNC_INSTRUCTION_NEW; + + const auto perms = !_rootPermissions.isNull() ? _rootPermissions + : _dirParentItem ? _dirParentItem->_remotePerm : _rootPermissions; + + if (perms.isNull()) { + // No permissions set + } else if (_dirItem->isDirectory() && !perms.hasPermission(RemotePermissions::CanAddSubDirectories)) { + qCWarning(lcDisco) << "checkForPermission: ERROR" << _dirItem->_file; + _dirItem->_instruction = CSYNC_INSTRUCTION_ERROR; + _dirItem->_errorString = tr("Not allowed because you don't have permission to add subfolders to that folder"); + const auto localPath = QString{_discoveryData->_localDir + _dirItem->_file}; + qCWarning(lcDisco) << "unexpected new folder in a read-only folder will be made read-write" << localPath; + FileSystem::setFolderPermissions(localPath, FileSystem::FolderPermissions::ReadWrite); + } + _dirItem->_direction = _dirItem->_direction == SyncFileItem::Up ? SyncFileItem::Down : SyncFileItem::Up; } if (_childModified && _dirItem->_instruction == CSYNC_INSTRUCTION_TYPE_CHANGE && !_dirItem->isDirectory()) { diff --git a/src/libsync/discovery.h b/src/libsync/discovery.h index 62d1f493c5132..840eb15d61169 100644 --- a/src/libsync/discovery.h +++ b/src/libsync/discovery.h @@ -108,8 +108,8 @@ class ProcessDirectoryJob : public QObject QueryMode queryLocal, QueryMode queryServer, qint64 lastSyncTimestamp, ProcessDirectoryJob *parent); - explicit ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, - QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent); + explicit ProcessDirectoryJob(DiscoveryPhase *data, PinState basePinState, const PathTuple &path, const SyncFileItemPtr &dirItem, const SyncFileItemPtr &parentDirItem, + QueryMode queryLocal, qint64 lastSyncTimestamp, QObject *parent); void start(); /** Start up to nbJobs, return the number of job started; emit finished() when done */ @@ -126,6 +126,7 @@ class ProcessDirectoryJob : public QObject } SyncFileItemPtr _dirItem; + SyncFileItemPtr _dirParentItem; private: struct Entries diff --git a/src/libsync/syncengine.cpp b/src/libsync/syncengine.cpp index 3470504e2709f..2c140d1019583 100644 --- a/src/libsync/syncengine.cpp +++ b/src/libsync/syncengine.cpp @@ -726,6 +726,7 @@ void SyncEngine::startSync() pinState, path, singleItemDiscoveryOptions().discoveryDirItem, + {}, localQueryMode, _journal->keyValueStoreGetInt("last_sync", 0), _discoveryPhase.data()