mirror of
https://github.com/nextcloud/server.git
synced 2026-04-28 17:48:40 -04:00
fix(trashbin): keep metadata consistent on move
Signed-off-by: Hoang Pham <hoangmaths96@gmail.com>
This commit is contained in:
parent
983106f099
commit
3edd9adc92
1 changed files with 78 additions and 56 deletions
|
|
@ -296,12 +296,60 @@ class Trashbin implements IEventListener {
|
|||
|
||||
$configuredTrashbinSize = static::getConfiguredTrashbinSize($owner);
|
||||
if ($configuredTrashbinSize >= 0 && $sourceInfo->getSize() >= $configuredTrashbinSize) {
|
||||
$trashStorage->releaseLock($trashInternalPath, ILockingProvider::LOCK_EXCLUSIVE, $lockingProvider);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$moveSuccessful = true;
|
||||
// there is still a possibility that the file has been deleted by a remote user
|
||||
$deletedBy = self::overwriteDeletedBy($user);
|
||||
|
||||
$deleteTrashRow = static function () use ($owner, $filename, $timestamp): void {
|
||||
$query = Server::get(IDBConnection::class)->getQueryBuilder();
|
||||
$query->delete('files_trash')
|
||||
->where($query->expr()->eq('user', $query->createNamedParameter($owner)))
|
||||
->andWhere($query->expr()->eq('id', $query->createNamedParameter($filename)))
|
||||
->andWhere($query->expr()->eq('timestamp', $query->createNamedParameter($timestamp)));
|
||||
$query->executeStatement();
|
||||
};
|
||||
|
||||
$query = Server::get(IDBConnection::class)->getQueryBuilder();
|
||||
$query->insert('files_trash')
|
||||
->setValue('id', $query->createNamedParameter($filename))
|
||||
->setValue('timestamp', $query->createNamedParameter($timestamp))
|
||||
->setValue('location', $query->createNamedParameter($location))
|
||||
->setValue('user', $query->createNamedParameter($owner))
|
||||
->setValue('deleted_by', $query->createNamedParameter($deletedBy));
|
||||
$inserted = false;
|
||||
try {
|
||||
$inserted = ($query->executeStatement() === 1);
|
||||
} catch (\Throwable $e) {
|
||||
Server::get(LoggerInterface::class)->error(
|
||||
'trash bin database insert failed',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'exception' => $e,
|
||||
'user' => $owner,
|
||||
'filename' => $filename,
|
||||
'timestamp' => $timestamp,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!$inserted) {
|
||||
Server::get(LoggerInterface::class)->error(
|
||||
'trash bin database couldn\'t be updated, skipping trash move',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $owner,
|
||||
'filename' => $filename,
|
||||
'timestamp' => $timestamp,
|
||||
]
|
||||
);
|
||||
$trashStorage->releaseLock($trashInternalPath, ILockingProvider::LOCK_EXCLUSIVE, $lockingProvider);
|
||||
return false;
|
||||
}
|
||||
|
||||
$moveSuccessful = true;
|
||||
try {
|
||||
$inCache = $sourceStorage->getCache()->inCache($sourceInternalPath);
|
||||
$trashStorage->moveFromStorage($sourceStorage, $sourceInternalPath, $trashInternalPath);
|
||||
if ($inCache) {
|
||||
|
|
@ -330,65 +378,39 @@ class Trashbin implements IEventListener {
|
|||
} else {
|
||||
$trashStorage->getUpdater()->remove($trashInternalPath);
|
||||
}
|
||||
return false;
|
||||
$moveSuccessful = false;
|
||||
}
|
||||
|
||||
if (!$moveSuccessful) {
|
||||
Server::get(LoggerInterface::class)->error(
|
||||
'trash move failed, removing trash metadata and payload',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $owner,
|
||||
'filename' => $filename,
|
||||
'timestamp' => $timestamp,
|
||||
]
|
||||
);
|
||||
$deleteTrashRow();
|
||||
if ($trashStorage->file_exists($trashInternalPath)) {
|
||||
if ($trashStorage->is_dir($trashInternalPath)) {
|
||||
$trashStorage->rmdir($trashInternalPath);
|
||||
} else {
|
||||
$trashStorage->unlink($trashInternalPath);
|
||||
}
|
||||
}
|
||||
$trashStorage->getUpdater()->remove($trashInternalPath);
|
||||
}
|
||||
|
||||
if ($moveSuccessful) {
|
||||
// there is still a possibility that the file has been deleted by a remote user
|
||||
$deletedBy = self::overwriteDeletedBy($user);
|
||||
Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', ['filePath' => Filesystem::normalizePath($file_path),
|
||||
'trashPath' => Filesystem::normalizePath(static::getTrashFilename($filename, $timestamp))]);
|
||||
|
||||
$query = Server::get(IDBConnection::class)->getQueryBuilder();
|
||||
$query->insert('files_trash')
|
||||
->setValue('id', $query->createNamedParameter($filename))
|
||||
->setValue('timestamp', $query->createNamedParameter($timestamp))
|
||||
->setValue('location', $query->createNamedParameter($location))
|
||||
->setValue('user', $query->createNamedParameter($owner))
|
||||
->setValue('deleted_by', $query->createNamedParameter($deletedBy));
|
||||
$inserted = false;
|
||||
try {
|
||||
$inserted = ($query->executeStatement() === 1);
|
||||
} catch (\Throwable $e) {
|
||||
Server::get(LoggerInterface::class)->error(
|
||||
'trash bin database insert failed',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'exception' => $e,
|
||||
'user' => $owner,
|
||||
'filename' => $filename,
|
||||
'timestamp' => $timestamp,
|
||||
]
|
||||
);
|
||||
}
|
||||
if (!$inserted) {
|
||||
Server::get(LoggerInterface::class)->error(
|
||||
'trash bin database couldn\'t be updated, removing trash payload',
|
||||
[
|
||||
'app' => 'files_trashbin',
|
||||
'user' => $owner,
|
||||
'filename' => $filename,
|
||||
'timestamp' => $timestamp,
|
||||
]
|
||||
);
|
||||
if ($trashStorage->file_exists($trashInternalPath)) {
|
||||
if ($trashStorage->is_dir($trashInternalPath)) {
|
||||
$trashStorage->rmdir($trashInternalPath);
|
||||
} else {
|
||||
$trashStorage->unlink($trashInternalPath);
|
||||
}
|
||||
}
|
||||
$trashStorage->getUpdater()->remove($trashInternalPath);
|
||||
$moveSuccessful = false;
|
||||
}
|
||||
if ($inserted) {
|
||||
Util::emitHook('\OCA\Files_Trashbin\Trashbin', 'post_moveToTrash', ['filePath' => Filesystem::normalizePath($file_path),
|
||||
'trashPath' => Filesystem::normalizePath(static::getTrashFilename($filename, $timestamp))]);
|
||||
self::retainVersions($filename, $owner, $ownerPath, $timestamp);
|
||||
|
||||
self::retainVersions($filename, $owner, $ownerPath, $timestamp);
|
||||
|
||||
// if owner !== user we need to also add a copy to the users trash
|
||||
if ($user !== $owner && $ownerOnly === false) {
|
||||
self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp);
|
||||
}
|
||||
// if owner !== user we need to also add a copy to the users trash
|
||||
if ($user !== $owner && $ownerOnly === false) {
|
||||
self::copyFilesToUser($ownerPath, $owner, $file_path, $user, $timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue