aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/files_trashbin/composer/composer/autoload_classmap.php1
-rw-r--r--apps/files_trashbin/composer/composer/autoload_static.php1
-rw-r--r--apps/files_trashbin/lib/Helper.php7
-rw-r--r--apps/files_trashbin/lib/Migration/Version1020Date20240403003535.php56
-rw-r--r--apps/files_trashbin/lib/Sabre/AbstractTrash.php5
-rw-r--r--apps/files_trashbin/lib/Sabre/ITrash.php3
-rw-r--r--apps/files_trashbin/lib/Sabre/TrashbinPlugin.php10
-rw-r--r--apps/files_trashbin/lib/Trash/ITrashItem.php5
-rw-r--r--apps/files_trashbin/lib/Trash/LegacyTrashBackend.php15
-rw-r--r--apps/files_trashbin/lib/Trash/TrashItem.php37
-rw-r--r--apps/files_trashbin/lib/Trashbin.php23
-rw-r--r--apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php10
12 files changed, 127 insertions, 46 deletions
diff --git a/apps/files_trashbin/composer/composer/autoload_classmap.php b/apps/files_trashbin/composer/composer/autoload_classmap.php
index f1bc38f1492..052063d3550 100644
--- a/apps/files_trashbin/composer/composer/autoload_classmap.php
+++ b/apps/files_trashbin/composer/composer/autoload_classmap.php
@@ -26,6 +26,7 @@ return array(
'OCA\\Files_Trashbin\\Listeners\\LoadAdditionalScripts' => $baseDir . '/../lib/Listeners/LoadAdditionalScripts.php',
'OCA\\Files_Trashbin\\Listeners\\SyncLivePhotosListener' => $baseDir . '/../lib/Listeners/SyncLivePhotosListener.php',
'OCA\\Files_Trashbin\\Migration\\Version1010Date20200630192639' => $baseDir . '/../lib/Migration/Version1010Date20200630192639.php',
+ 'OCA\\Files_Trashbin\\Migration\\Version1020Date20240403003535' => $baseDir . '/../lib/Migration/Version1020Date20240403003535.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrash' => $baseDir . '/../lib/Sabre/AbstractTrash.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrashFile' => $baseDir . '/../lib/Sabre/AbstractTrashFile.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrashFolder' => $baseDir . '/../lib/Sabre/AbstractTrashFolder.php',
diff --git a/apps/files_trashbin/composer/composer/autoload_static.php b/apps/files_trashbin/composer/composer/autoload_static.php
index 4c4b33574af..4f5227b8889 100644
--- a/apps/files_trashbin/composer/composer/autoload_static.php
+++ b/apps/files_trashbin/composer/composer/autoload_static.php
@@ -41,6 +41,7 @@ class ComposerStaticInitFiles_Trashbin
'OCA\\Files_Trashbin\\Listeners\\LoadAdditionalScripts' => __DIR__ . '/..' . '/../lib/Listeners/LoadAdditionalScripts.php',
'OCA\\Files_Trashbin\\Listeners\\SyncLivePhotosListener' => __DIR__ . '/..' . '/../lib/Listeners/SyncLivePhotosListener.php',
'OCA\\Files_Trashbin\\Migration\\Version1010Date20200630192639' => __DIR__ . '/..' . '/../lib/Migration/Version1010Date20200630192639.php',
+ 'OCA\\Files_Trashbin\\Migration\\Version1020Date20240403003535' => __DIR__ . '/..' . '/../lib/Migration/Version1020Date20240403003535.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrash' => __DIR__ . '/..' . '/../lib/Sabre/AbstractTrash.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrashFile' => __DIR__ . '/..' . '/../lib/Sabre/AbstractTrashFile.php',
'OCA\\Files_Trashbin\\Sabre\\AbstractTrashFolder' => __DIR__ . '/..' . '/../lib/Sabre/AbstractTrashFolder.php',
diff --git a/apps/files_trashbin/lib/Helper.php b/apps/files_trashbin/lib/Helper.php
index 61d8eb9c715..ba28751e99f 100644
--- a/apps/files_trashbin/lib/Helper.php
+++ b/apps/files_trashbin/lib/Helper.php
@@ -60,7 +60,7 @@ class Helper {
$absoluteDir = $view->getAbsolutePath($dir);
$internalPath = $mount->getInternalPath($absoluteDir);
- $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($user);
+ $extraData = \OCA\Files_Trashbin\Trashbin::getExtraData($user);
$dirContent = $storage->getCache()->getFolderContents($mount->getInternalPath($view->getAbsolutePath($dir)));
foreach ($dirContent as $entry) {
$entryName = $entry->getName();
@@ -76,8 +76,8 @@ class Helper {
}
$originalPath = '';
$originalName = substr($entryName, 0, -strlen($timestamp) - 2);
- if (isset($originalLocations[$originalName][$timestamp])) {
- $originalPath = $originalLocations[$originalName][$timestamp];
+ if (isset($extraData[$originalName][$timestamp]['location'])) {
+ $originalPath = $extraData[$originalName][$timestamp]['location'];
if (substr($originalPath, -1) === '/') {
$originalPath = substr($originalPath, 0, -1);
}
@@ -101,6 +101,7 @@ class Helper {
$i['extraData'] = $originalName;
}
}
+ $i['deletedBy'] = $extraData[$originalName][$timestamp]['deletedBy'] ?? null;
$result[] = new FileInfo($absoluteDir . '/' . $i['name'], $storage, $internalPath . '/' . $i['name'], $i, $mount);
}
diff --git a/apps/files_trashbin/lib/Migration/Version1020Date20240403003535.php b/apps/files_trashbin/lib/Migration/Version1020Date20240403003535.php
new file mode 100644
index 00000000000..ea7ebefe5b1
--- /dev/null
+++ b/apps/files_trashbin/lib/Migration/Version1020Date20240403003535.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright 2024 Christopher Ng <chrng8@gmail.com>
+ *
+ * @author Christopher Ng <chrng8@gmail.com>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\Files_Trashbin\Migration;
+
+use Closure;
+use OCP\DB\ISchemaWrapper;
+use OCP\DB\Types;
+use OCP\Migration\IOutput;
+use OCP\Migration\SimpleMigrationStep;
+
+class Version1020Date20240403003535 extends SimpleMigrationStep {
+
+ /**
+ * @param Closure(): ISchemaWrapper $schemaClosure
+ */
+ public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
+ /** @var ISchemaWrapper $schema */
+ $schema = $schemaClosure();
+
+ if (!$schema->hasTable('files_trash')) {
+ return null;
+ }
+
+ $table = $schema->getTable('files_trash');
+ $table->addColumn('deleted_by', Types::STRING, [
+ 'notnull' => false,
+ 'length' => 64,
+ ]);
+
+ return $schema;
+ }
+}
diff --git a/apps/files_trashbin/lib/Sabre/AbstractTrash.php b/apps/files_trashbin/lib/Sabre/AbstractTrash.php
index e02e4c5b8ba..6e0ff428207 100644
--- a/apps/files_trashbin/lib/Sabre/AbstractTrash.php
+++ b/apps/files_trashbin/lib/Sabre/AbstractTrash.php
@@ -28,6 +28,7 @@ namespace OCA\Files_Trashbin\Sabre;
use OCA\Files_Trashbin\Trash\ITrashItem;
use OCA\Files_Trashbin\Trash\ITrashManager;
use OCP\Files\FileInfo;
+use OCP\IUser;
abstract class AbstractTrash implements ITrash {
/** @var ITrashItem */
@@ -89,6 +90,10 @@ abstract class AbstractTrash implements ITrash {
return $this->data->getTitle();
}
+ public function getDeletedBy(): ?IUser {
+ return $this->data->getDeletedBy();
+ }
+
public function delete() {
$this->trashManager->removeItem($this->data);
}
diff --git a/apps/files_trashbin/lib/Sabre/ITrash.php b/apps/files_trashbin/lib/Sabre/ITrash.php
index b6b4e70f3b9..c5063df1d11 100644
--- a/apps/files_trashbin/lib/Sabre/ITrash.php
+++ b/apps/files_trashbin/lib/Sabre/ITrash.php
@@ -27,6 +27,7 @@ declare(strict_types=1);
namespace OCA\Files_Trashbin\Sabre;
use OCP\Files\FileInfo;
+use OCP\IUser;
interface ITrash {
public function restore(): bool;
@@ -39,6 +40,8 @@ interface ITrash {
public function getDeletionTime(): int;
+ public function getDeletedBy(): ?IUser;
+
public function getSize(): int|float;
public function getFileId(): int;
diff --git a/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php b/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php
index 72b7332d9b1..512a2c072ea 100644
--- a/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php
+++ b/apps/files_trashbin/lib/Sabre/TrashbinPlugin.php
@@ -41,6 +41,8 @@ class TrashbinPlugin extends ServerPlugin {
public const TRASHBIN_ORIGINAL_LOCATION = '{http://nextcloud.org/ns}trashbin-original-location';
public const TRASHBIN_DELETION_TIME = '{http://nextcloud.org/ns}trashbin-deletion-time';
public const TRASHBIN_TITLE = '{http://nextcloud.org/ns}trashbin-title';
+ public const TRASHBIN_DELETED_BY_ID = '{http://nextcloud.org/ns}trashbin-deleted-by-id';
+ public const TRASHBIN_DELETED_BY_DISPLAY_NAME = '{http://nextcloud.org/ns}trashbin-deleted-by-display-name';
/** @var Server */
private $server;
@@ -83,6 +85,14 @@ class TrashbinPlugin extends ServerPlugin {
return $node->getDeletionTime();
});
+ $propFind->handle(self::TRASHBIN_DELETED_BY_ID, function () use ($node) {
+ return $node->getDeletedBy()?->getUID();
+ });
+
+ $propFind->handle(self::TRASHBIN_DELETED_BY_DISPLAY_NAME, function () use ($node) {
+ return $node->getDeletedBy()?->getDisplayName();
+ });
+
$propFind->handle(FilesPlugin::SIZE_PROPERTYNAME, function () use ($node) {
return $node->getSize();
});
diff --git a/apps/files_trashbin/lib/Trash/ITrashItem.php b/apps/files_trashbin/lib/Trash/ITrashItem.php
index 0f9c8144a59..bcce5c6876e 100644
--- a/apps/files_trashbin/lib/Trash/ITrashItem.php
+++ b/apps/files_trashbin/lib/Trash/ITrashItem.php
@@ -77,5 +77,10 @@ interface ITrashItem extends FileInfo {
*/
public function getUser(): IUser;
+ /**
+ * @since 30.0.0
+ */
+ public function getDeletedBy(): ?IUser;
+
public function getTitle(): string;
}
diff --git a/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php b/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php
index a608dc08331..fa71d386794 100644
--- a/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php
+++ b/apps/files_trashbin/lib/Trash/LegacyTrashBackend.php
@@ -33,16 +33,16 @@ use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorage;
use OCP\IUser;
+use OCP\IUserManager;
class LegacyTrashBackend implements ITrashBackend {
/** @var array */
private $deletedFiles = [];
- /** @var IRootFolder */
- private $rootFolder;
-
- public function __construct(IRootFolder $rootFolder) {
- $this->rootFolder = $rootFolder;
+ public function __construct(
+ private IRootFolder $rootFolder,
+ private IUserManager $userManager,
+ ) {
}
/**
@@ -59,6 +59,8 @@ class LegacyTrashBackend implements ITrashBackend {
if (!$originalLocation) {
$originalLocation = $file->getName();
}
+ /** @psalm-suppress UndefinedInterfaceMethod */
+ $deletedBy = $this->userManager->get($file['deletedBy']) ?? $parent?->getDeletedBy();
$trashFilename = Trashbin::getTrashFilename($file->getName(), $file->getMtime());
return new TrashItem(
$this,
@@ -66,7 +68,8 @@ class LegacyTrashBackend implements ITrashBackend {
$file->getMTime(),
$parentTrashPath . '/' . ($isRoot ? $trashFilename : $file->getName()),
$file,
- $user
+ $user,
+ $deletedBy,
);
}, $items);
}
diff --git a/apps/files_trashbin/lib/Trash/TrashItem.php b/apps/files_trashbin/lib/Trash/TrashItem.php
index 5c9775c6876..79b9b67d278 100644
--- a/apps/files_trashbin/lib/Trash/TrashItem.php
+++ b/apps/files_trashbin/lib/Trash/TrashItem.php
@@ -27,33 +27,16 @@ use OCP\Files\FileInfo;
use OCP\IUser;
class TrashItem implements ITrashItem {
- /** @var ITrashBackend */
- private $backend;
- /** @var string */
- private $orignalLocation;
- /** @var int */
- private $deletedTime;
- /** @var string */
- private $trashPath;
- /** @var FileInfo */
- private $fileInfo;
- /** @var IUser */
- private $user;
public function __construct(
- ITrashBackend $backend,
- string $originalLocation,
- int $deletedTime,
- string $trashPath,
- FileInfo $fileInfo,
- IUser $user
+ private ITrashBackend $backend,
+ private string $originalLocation,
+ private int $deletedTime,
+ private string $trashPath,
+ private FileInfo $fileInfo,
+ private IUser $user,
+ private ?IUser $deletedBy,
) {
- $this->backend = $backend;
- $this->orignalLocation = $originalLocation;
- $this->deletedTime = $deletedTime;
- $this->trashPath = $trashPath;
- $this->fileInfo = $fileInfo;
- $this->user = $user;
}
public function getTrashBackend(): ITrashBackend {
@@ -61,7 +44,7 @@ class TrashItem implements ITrashItem {
}
public function getOriginalLocation(): string {
- return $this->orignalLocation;
+ return $this->originalLocation;
}
public function getDeletedTime(): int {
@@ -192,6 +175,10 @@ class TrashItem implements ITrashItem {
return $this->fileInfo->getParentId();
}
+ public function getDeletedBy(): ?IUser {
+ return $this->deletedBy;
+ }
+
/**
* @inheritDoc
* @return array<string, int|string|bool|float|string[]|int[]>
diff --git a/apps/files_trashbin/lib/Trashbin.php b/apps/files_trashbin/lib/Trashbin.php
index ced40313d62..e5b22f86bd0 100644
--- a/apps/files_trashbin/lib/Trashbin.php
+++ b/apps/files_trashbin/lib/Trashbin.php
@@ -126,24 +126,23 @@ class Trashbin {
}
/**
- * get original location of files for user
+ * get original location and deleted by of files for user
*
* @param string $user
- * @return array (filename => array (timestamp => original location))
+ * @return array<string, array<string, array{location: string, deletedBy: string}>>
*/
- public static function getLocations($user) {
+ public static function getExtraData($user) {
$query = \OC::$server->getDatabaseConnection()->getQueryBuilder();
- $query->select('id', 'timestamp', 'location')
+ $query->select('id', 'timestamp', 'location', 'deleted_by')
->from('files_trash')
->where($query->expr()->eq('user', $query->createNamedParameter($user)));
$result = $query->executeQuery();
$array = [];
while ($row = $result->fetch()) {
- if (isset($array[$row['id']])) {
- $array[$row['id']][$row['timestamp']] = $row['location'];
- } else {
- $array[$row['id']] = [$row['timestamp'] => $row['location']];
- }
+ $array[$row['id']][$row['timestamp']] = [
+ 'location' => (string)$row['location'],
+ 'deletedBy' => (string)$row['deleted_by'],
+ ];
}
$result->closeCursor();
return $array;
@@ -228,7 +227,8 @@ class Trashbin {
->setValue('id', $query->createNamedParameter($targetFilename))
->setValue('timestamp', $query->createNamedParameter($timestamp))
->setValue('location', $query->createNamedParameter($targetLocation))
- ->setValue('user', $query->createNamedParameter($user));
+ ->setValue('user', $query->createNamedParameter($user))
+ ->setValue('deleted_by', $query->createNamedParameter($user));
$result = $query->executeStatement();
if (!$result) {
\OC::$server->get(LoggerInterface::class)->error('trash bin database couldn\'t be updated for the files owner', ['app' => 'files_trashbin']);
@@ -358,7 +358,8 @@ class Trashbin {
->setValue('id', $query->createNamedParameter($filename))
->setValue('timestamp', $query->createNamedParameter($timestamp))
->setValue('location', $query->createNamedParameter($location))
- ->setValue('user', $query->createNamedParameter($owner));
+ ->setValue('user', $query->createNamedParameter($owner))
+ ->setValue('deleted_by', $query->createNamedParameter($user));
$result = $query->executeStatement();
if (!$result) {
\OC::$server->get(LoggerInterface::class)->error('trash bin database couldn\'t be updated', ['app' => 'files_trashbin']);
diff --git a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php
index 971d2a7d60b..5b3be5aead6 100644
--- a/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php
+++ b/apps/files_trashbin/lib/UserMigration/TrashbinMigrator.php
@@ -96,7 +96,15 @@ class TrashbinMigrator implements IMigrator, ISizeEstimationMigrator {
}
$output->writeln("Exporting trashbin files…");
$exportDestination->copyFolder($trashbinFolder, static::PATH_FILES_FOLDER);
- $originalLocations = \OCA\Files_Trashbin\Trashbin::getLocations($uid);
+ $originalLocations = [];
+ // TODO Export all extra data and bump migrator to v2
+ foreach (\OCA\Files_Trashbin\Trashbin::getExtraData($uid) as $filename => $extraData) {
+ $locationData = [];
+ foreach ($extraData as $timestamp => ['location' => $location]) {
+ $locationData[$timestamp] = $location;
+ }
+ $originalLocations[$filename] = $locationData;
+ }
$exportDestination->addFileContents(static::PATH_LOCATIONS_FILE, json_encode($originalLocations));
} catch (NotFoundException $e) {
$output->writeln("No trashbin to export…");