Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable29] Encryption trash fixes #3484

Merged
merged 9 commits into from
Dec 13, 2024
3 changes: 2 additions & 1 deletion lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ public function register(IRegistrationContext $context): void {
$c->get(MountProvider::class),
$c->get(ACLManagerFactory::class),
$c->get(IRootFolder::class),
$c->get(LoggerInterface::class)
$c->get(LoggerInterface::class),
$c->get(IUserSession::class),
);
$hasVersionApp = interface_exists(\OCA\Files_Versions\Versions\IVersionBackend::class);
if ($hasVersionApp) {
Expand Down
14 changes: 10 additions & 4 deletions lib/Mount/GroupFolderStorage.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,17 @@
use OC\Files\ObjectStore\ObjectStoreScanner;
use OC\Files\ObjectStore\ObjectStoreStorage;
use OC\Files\Storage\Wrapper\Quota;
use OCP\Files\Cache\ICache;
use OCP\Files\Cache\ICacheEntry;
use OCP\IUser;
use OCP\IUserSession;

class GroupFolderStorage extends Quota {
private int $folderId;
private ICacheEntry $rootEntry;
private ?ICacheEntry $rootEntry;
private IUserSession $userSession;
private ?IUser $mountOwner = null;
/** @var RootEntryCache|null */
private ?IUser $mountOwner;
/** @var ICache|null */
public $cache = null;

public function __construct($parameters) {
Expand Down Expand Up @@ -68,7 +69,12 @@ public function getCache($path = '', $storage = null) {
$storage = $this;
}

$this->cache = new RootEntryCache(parent::getCache($path, $storage), $this->rootEntry);
$cache = parent::getCache($path, $storage);
if ($this->rootEntry !== null) {
$cache = new RootEntryCache($cache, $this->rootEntry);
}
$this->cache = $cache;

return $this->cache;
}

Expand Down
125 changes: 90 additions & 35 deletions lib/Mount/MountProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
$aclManager = $this->aclManagerFactory->getACLManager($user, $this->getRootStorageId());
$rootRules = $aclManager->getRelevantRulesForPath($aclRootPaths);

return array_values(array_filter(array_map(function ($folder) use ($user, $loader, $conflicts, $aclManager, $rootRules) {
return array_merge(...array_filter(array_map(function (array $folder) use ($user, $loader, $conflicts, $aclManager, $rootRules): ?array {
// check for existing files in the user home and rename them if needed
$originalFolderName = $folder['mount_point'];
if (in_array($originalFolderName, $conflicts)) {
Expand All @@ -159,7 +159,7 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
$userStorage->getPropagator()->propagateChange("files/$folderName", time());
}

return $this->getMount(
$mount = $this->getMount(
$folder['folder_id'],
'/' . $user->getUID() . '/files/' . $folder['mount_point'],
$folder['permissions'],
Expand All @@ -171,6 +171,22 @@ public function getMountsForUser(IUser $user, IStorageFactory $loader) {
$aclManager,
$rootRules
);
if (!$mount) {
return null;
}
$trashMount = $this->getTrashMount(
$folder['folder_id'],
'/' . $user->getUID() . '/files_trashbin/groupfolders/' . $folder['folder_id'],
$folder['quota'],
$loader,
$user
);

return [
$mount,
$trashMount,
];

}, $folders)));
}

Expand All @@ -193,16 +209,16 @@ private function getCurrentUID(): ?string {
}

public function getMount(
int $id,
string $mountPoint,
int $permissions,
int $quota,
?ICacheEntry $cacheEntry = null,
int $id,
string $mountPoint,
int $permissions,
int $quota,
?ICacheEntry $cacheEntry = null,
?IStorageFactory $loader = null,
bool $acl = false,
?IUser $user = null,
?ACLManager $aclManager = null,
array $rootRules = []
bool $acl = false,
?IUser $user = null,
?ACLManager $aclManager = null,
array $rootRules = []
): ?IMountPoint {
if (!$cacheEntry) {
// trigger folder creation
Expand Down Expand Up @@ -230,52 +246,91 @@ public function getMount(
$cacheEntry['permissions'] &= $aclRootPermissions;
}

$quotaStorage = $this->getGroupFolderStorage($id, $storage, $user, $rootPath, $quota, $cacheEntry);

$maskedStore = new PermissionsMask([
'storage' => $quotaStorage,
'mask' => $permissions,
]);

if (!$this->allowRootShare) {
$maskedStore = new RootPermissionsMask([
'storage' => $maskedStore,
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
]);
}

return new GroupMountPoint(
$id,
$maskedStore,
$mountPoint,
null,
$loader
);
}

public function getTrashMount(
int $id,
string $mountPoint,
int $quota,
IStorageFactory $loader,
IUser $user,
): IMountPoint {

$storage = $this->getRootFolder()->getStorage();

$storage->setOwner($user->getUID());

$trashPath = $this->getRootFolder()->getInternalPath() . '/trash/' . $id;

$trashStorage = $this->getGroupFolderStorage($id, $storage, $user, $trashPath, $quota, null);

return new GroupMountPoint(
$id,
$trashStorage,
$mountPoint,
null,
$loader
);
}

public function getGroupFolderStorage(
int $id,
IStorage $rootStorage,
?IUser $user,
string $rootPath,
int $quota,
?ICacheEntry $rootCacheEntry,
): IStorage {
if ($this->enableEncryption) {
$baseStorage = new GroupFolderEncryptionJail([
'storage' => $storage,
'root' => $rootPath
'storage' => $rootStorage,
'root' => $rootPath,
]);
$quotaStorage = new GroupFolderStorage([
'storage' => $baseStorage,
'quota' => $quota,
'folder_id' => $id,
'rootCacheEntry' => $cacheEntry,
'rootCacheEntry' => $rootCacheEntry,
'userSession' => $this->userSession,
'mountOwner' => $user,
]);
} else {
$baseStorage = new Jail([
'storage' => $storage,
'root' => $rootPath
'storage' => $rootStorage,
'root' => $rootPath,
]);
$quotaStorage = new GroupFolderNoEncryptionStorage([
'storage' => $baseStorage,
'quota' => $quota,
'folder_id' => $id,
'rootCacheEntry' => $cacheEntry,
'rootCacheEntry' => $rootCacheEntry,
'userSession' => $this->userSession,
'mountOwner' => $user,
]);
}
$maskedStore = new PermissionsMask([
'storage' => $quotaStorage,
'mask' => $permissions
]);

if (!$this->allowRootShare) {
$maskedStore = new RootPermissionsMask([
'storage' => $maskedStore,
'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE,
]);
}

return new GroupMountPoint(
$id,
$maskedStore,
$mountPoint,
null,
$loader
);
return $quotaStorage;
}

public function getJailPath(int $folderId): string {
Expand Down
14 changes: 1 addition & 13 deletions lib/Trash/GroupTrashItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

namespace OCA\GroupFolders\Trash;

use OC\Files\Storage\Wrapper\Jail;
use OCA\Files_Trashbin\Trash\ITrashBackend;
use OCA\Files_Trashbin\Trash\TrashItem;
use OCP\Files\FileInfo;
Expand Down Expand Up @@ -59,18 +58,7 @@ public function getTitle(): string {
return $this->getGroupFolderMountPoint() . '/' . $this->getOriginalLocation();
}

public function getStorage() {
// get the unjailed storage, since the trash item is outside the jail
// (the internal path is also unjailed)
$groupFolderStorage = parent::getStorage();
if ($groupFolderStorage->instanceOfStorage(Jail::class)) {
/** @var Jail $groupFolderStorage */
return $groupFolderStorage->getUnjailedStorage();
}
return $groupFolderStorage;
}

public function getMtime() {
public function getMtime(): int {
// trashbin is currently (incorrectly) assuming these to be the same
return $this->getDeletedTime();
}
Expand Down
Loading
Loading