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();
|
||||
|
||||
// Function to gradually check conditions for accepting a move-candidate
|
||||
const auto isExternalStorage = base._remotePerm.hasPermission(RemotePermissions::IsMounted);
|
||||
auto moveCheck = [&]() {
|
||||
if (!base.isValid()) {
|
||||
qCInfo(lcDisco) << "Not a move, no item in db with inode" << localEntry.inode;
|
||||
|
@ -1397,19 +1396,6 @@ void ProcessDirectoryJob::processFileAnalyzeLocalInfo(
|
|||
|
||||
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 isE2eeMove = isMove && (base.isE2eEncrypted() || isInsideEncryptedTree());
|
||||
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");
|
||||
}
|
||||
|
||||
// If it's not a move/rename, it's just a local-NEW
|
||||
if (!isExternalStorageRename()) {
|
||||
if ((!isMove || (isE2eeMove && !isE2eeMoveOnlineOnlyItemWithCfApi))) {
|
||||
if (base.isE2eEncrypted()) {
|
||||
// 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
|
||||
item->_e2eEncryptionStatus = EncryptionStatusEnums::fromDbEncryptionStatus(base._e2eEncryptionStatus);
|
||||
item->_e2eEncryptionServerCapability = EncryptionStatusEnums::fromEndToEndEncryptionApiVersion(_discoveryData->_account->capabilities().clientSideEncryptionVersion());
|
||||
}
|
||||
postProcessLocalNew();
|
||||
finalize();
|
||||
// If it's not a move it's just a local-NEW
|
||||
if (!isMove || (isE2eeMove && !isE2eeMoveOnlineOnlyItemWithCfApi)) {
|
||||
if (base.isE2eEncrypted()) {
|
||||
// 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
|
||||
item->_e2eEncryptionStatus = EncryptionStatusEnums::fromDbEncryptionStatus(base._e2eEncryptionStatus);
|
||||
item->_e2eEncryptionServerCapability = EncryptionStatusEnums::fromEndToEndEncryptionApiVersion(_discoveryData->_account->capabilities().clientSideEncryptionVersion());
|
||||
}
|
||||
postProcessLocalNew();
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 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;
|
||||
// Here we know the new location can't be uploaded: must prevent the source delete.
|
||||
// Two cases: either the source item was already processed or not.
|
||||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||
if (wasDeletedOnClient.first) {
|
||||
// More complicated. The REMOVE is canceled. Restore will happen next sync.
|
||||
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;
|
||||
}
|
||||
|
||||
// Here we know the new location can't be uploaded: must prevent the source delete.
|
||||
// Two cases: either the source item was already processed or not.
|
||||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||
if (wasDeletedOnClient.first) {
|
||||
// More complicated. The REMOVE is canceled. Restore will happen next sync.
|
||||
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;
|
||||
_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;
|
||||
}
|
||||
|
||||
auto wasDeletedOnClient = _discoveryData->findAndCancelDeletedJob(originalPath);
|
||||
|
|
Loading…
Reference in a new issue