mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-22 13:05:51 +03:00
Only check for external storage permissions when it is a folder.
Signed-off-by: Camila Ayres <hello@camilasan.com>
This commit is contained in:
parent
0965deaa2f
commit
e38a9f181a
1 changed files with 52 additions and 67 deletions
|
@ -1348,7 +1348,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
||||||
const auto originalPath = base.path();
|
const auto originalPath = base.path();
|
||||||
|
|
||||||
// Function to gradually check conditions for accepting a move-candidate
|
// Function to gradually check conditions for accepting a move-candidate
|
||||||
const auto isExternalStorage = base._remotePerm.hasPermission(RemotePermissions::IsMounted);
|
|
||||||
auto moveCheck = [&]() {
|
auto moveCheck = [&]() {
|
||||||
if (!base.isValid()) {
|
if (!base.isValid()) {
|
||||||
qCInfo(lcDisco) << "Not a move, no item in db with inode" << localEntry.inode;
|
qCInfo(lcDisco) << "Not a move, no item in db with inode" << localEntry.inode;
|
||||||
|
@ -1397,19 +1396,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isExternalStorageRename = [&] {
|
|
||||||
OCC::SyncJournalFileRecord dbRecord;
|
|
||||||
const auto validRecord = _discoveryData->_statedb->getFileRecordByInode(localEntry.inode, &dbRecord);
|
|
||||||
qCInfo(lcDisco) << "File is saved in DB:" << validRecord;
|
|
||||||
qCInfo(lcDisco) << "File is in external storage:" << isExternalStorage;
|
|
||||||
if (validRecord && isExternalStorage) {
|
|
||||||
qCInfo(lcDisco) << "Try to process rename for path" << dbRecord._path << "and inode" << dbRecord._inode;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
const auto isMove = moveCheck();
|
const auto isMove = moveCheck();
|
||||||
const auto isE2eeMove = isMove && (base.isE2eEncrypted() || isInsideEncryptedTree());
|
const auto isE2eeMove = isMove && (base.isE2eEncrypted() || isInsideEncryptedTree());
|
||||||
const auto isCfApiVfsMode = _discoveryData->_syncOptions._vfs && _discoveryData->_syncOptions._vfs->mode() == Vfs::WindowsCfApi;
|
const auto isCfApiVfsMode = _discoveryData->_syncOptions._vfs && _discoveryData->_syncOptions._vfs->mode() == Vfs::WindowsCfApi;
|
||||||
|
@ -1423,64 +1409,63 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
||||||
item->_errorString = tr("Moved to invalid target, restoring");
|
item->_errorString = tr("Moved to invalid target, restoring");
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not a move/rename, it's just a local-NEW
|
// If it's not a move it's just a local-NEW
|
||||||
if (!isExternalStorageRename()) {
|
if (!isMove || (isE2eeMove && !isE2eeMoveOnlineOnlyItemWithCfApi)) {
|
||||||
if ((!isMove || (isE2eeMove && !isE2eeMoveOnlineOnlyItemWithCfApi))) {
|
if (base.isE2eEncrypted()) {
|
||||||
if (base.isE2eEncrypted()) {
|
// renaming the encrypted folder is done via remove + re-upload hence we need to mark the newly created folder as encrypted
|
||||||
// renaming the encrypted folder is done via remove + re-upload hence we need to mark the newly created folder as encrypted
|
// base is a record in the SyncJournal database that contains the data about the being-renamed folder with it's old name and encryption information
|
||||||
// base is a record in the SyncJournal database that contains the data about the being-renamed folder with it's old name and encryption information
|
item->_e2eEncryptionStatus = EncryptionStatusEnums::fromDbEncryptionStatus(base._e2eEncryptionStatus);
|
||||||
item->_e2eEncryptionStatus = EncryptionStatusEnums::fromDbEncryptionStatus(base._e2eEncryptionStatus);
|
item->_e2eEncryptionServerCapability = EncryptionStatusEnums::fromEndToEndEncryptionApiVersion(_discoveryData->_account->capabilities().clientSideEncryptionVersion());
|
||||||
item->_e2eEncryptionServerCapability = EncryptionStatusEnums::fromEndToEndEncryptionApiVersion(_discoveryData->_account->capabilities().clientSideEncryptionVersion());
|
}
|
||||||
}
|
postProcessLocalNew();
|
||||||
postProcessLocalNew();
|
finalize();
|
||||||
finalize();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check local permission if we are allowed to put move the file here
|
||||||
|
// Technically we should use the permissions from the server, but we'll assume it is the same
|
||||||
|
const auto serverHasMountRootProperty = _discoveryData->_account->serverHasMountRootProperty();
|
||||||
|
const auto isExternalStorage = base._remotePerm.hasPermission(RemotePermissions::IsMounted) && base.isDirectory();
|
||||||
|
const auto movePerms = checkMovePermissions(base._remotePerm, originalPath, item->isDirectory());
|
||||||
|
if (!movePerms.sourceOk || !movePerms.destinationOk || (serverHasMountRootProperty && isExternalStorage) || isE2eeMoveOnlineOnlyItemWithCfApi) {
|
||||||
|
qCInfo(lcDisco) << "Move without permission to rename base file, "
|
||||||
|
<< "source:" << movePerms.sourceOk
|
||||||
|
<< ", target:" << movePerms.destinationOk
|
||||||
|
<< ", targetNew:" << movePerms.destinationNewOk
|
||||||
|
<< ", isExternalStorage:" << isExternalStorage
|
||||||
|
<< ", serverHasMountRootProperty:" << serverHasMountRootProperty
|
||||||
|
<< ", base._remotePerm:" << base._remotePerm.toString()
|
||||||
|
<< ", base.path():" << base.path();
|
||||||
|
|
||||||
|
// If we can create the destination, do that.
|
||||||
|
// Permission errors on the destination will be handled by checkPermissions later.
|
||||||
|
postProcessLocalNew();
|
||||||
|
finalize();
|
||||||
|
|
||||||
|
// If the destination upload will work, we're fine with the source deletion.
|
||||||
|
// If the source deletion can't work, checkPermissions will error.
|
||||||
|
// In case of external storage mounted folders we are never allowed to move/delete them
|
||||||
|
if (movePerms.destinationNewOk && !isExternalStorage && !isE2eeMoveOnlineOnlyItemWithCfApi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check local permission if we are allowed to put move the file here
|
// Here we know the new location can't be uploaded: must prevent the source delete.
|
||||||
// Technically we should use the permissions from the server, but we'll assume it is the same
|
// Two cases: either the source item was already processed or not.
|
||||||
const auto serverHasMountRootProperty = _discoveryData->_account->serverHasMountRootProperty();
|
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||||
const auto movePerms = checkMovePermissions(base._remotePerm, originalPath, item->isDirectory());
|
if (wasDeletedOnClient.first) {
|
||||||
if (!movePerms.sourceOk || !movePerms.destinationOk || (serverHasMountRootProperty && isExternalStorage) || isE2eeMoveOnlineOnlyItemWithCfApi) {
|
// More complicated. The REMOVE is canceled. Restore will happen next sync.
|
||||||
qCInfo(lcDisco) << "Move without permission to rename base file, "
|
qCInfo(lcDisco) << "Undid remove instruction on source" << originalPath;
|
||||||
<< "source:" << movePerms.sourceOk
|
if (!_discoveryData->_statedb->deleteFileRecord(originalPath, true)) {
|
||||||
<< ", target:" << movePerms.destinationOk
|
qCWarning(lcDisco) << "Failed to delete a file record from the local DB" << originalPath;
|
||||||
<< ", targetNew:" << movePerms.destinationNewOk
|
|
||||||
<< ", isExternalStorage:" << isExternalStorage
|
|
||||||
<< ", serverHasMountRootProperty:" << serverHasMountRootProperty
|
|
||||||
<< ", base._remotePerm:" << base._remotePerm.toString()
|
|
||||||
<< ", base.path():" << base.path();
|
|
||||||
|
|
||||||
// If we can create the destination, do that.
|
|
||||||
// Permission errors on the destination will be handled by checkPermissions later.
|
|
||||||
postProcessLocalNew();
|
|
||||||
finalize();
|
|
||||||
|
|
||||||
// If the destination upload will work, we're fine with the source deletion.
|
|
||||||
// If the source deletion can't work, checkPermissions will error.
|
|
||||||
// In case of external storage mounted folders we are never allowed to move/delete them
|
|
||||||
if (movePerms.destinationNewOk && !isExternalStorage && !isE2eeMoveOnlineOnlyItemWithCfApi) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
_discoveryData->_statedb->schedulePathForRemoteDiscovery(originalPath);
|
||||||
// Here we know the new location can't be uploaded: must prevent the source delete.
|
_discoveryData->_anotherSyncNeeded = true;
|
||||||
// Two cases: either the source item was already processed or not.
|
} else {
|
||||||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
// Signal to future checkPermissions() to forbid the REMOVE and set to restore instead
|
||||||
if (wasDeletedOnClient.first) {
|
qCInfo(lcDisco) << "Preventing future remove on source" << originalPath;
|
||||||
// More complicated. The REMOVE is canceled. Restore will happen next sync.
|
_discoveryData->_forbiddenDeletes[originalPath + '/'] = true;
|
||||||
qCInfo(lcDisco) << "Undid remove instruction on source" << originalPath;
|
|
||||||
if (!_discoveryData->_statedb->deleteFileRecord(originalPath, true)) {
|
|
||||||
qCWarning(lcDisco) << "Failed to delete a file record from the local DB" << originalPath;
|
|
||||||
}
|
|
||||||
_discoveryData->_statedb->schedulePathForRemoteDiscovery(originalPath);
|
|
||||||
_discoveryData->_anotherSyncNeeded = true;
|
|
||||||
} else {
|
|
||||||
// Signal to future checkPermissions() to forbid the REMOVE and set to restore instead
|
|
||||||
qCInfo(lcDisco) << "Preventing future remove on source" << originalPath;
|
|
||||||
_discoveryData->_forbiddenDeletes[originalPath + '/'] = true;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||||
|
|
Loading…
Reference in a new issue