diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 5764eb862..e2a10e475 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -8,7 +8,6 @@ namespace OCA\GroupFolders\AppInfo; -use OC\Files\Node\LazyFolder; use OCA\Circles\Events\CircleDestroyedEvent; use OCA\DAV\Connector\Sabre\Principal; use OCA\Files\Event\LoadAdditionalScriptsEvent; @@ -45,10 +44,8 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\IMountProviderCollection; use OCP\Files\Events\Node\NodeRenamedEvent; -use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\Mount\IMountManager; -use OCP\Files\NotFoundException; use OCP\Files\Storage\IStorageFactory; use OCP\Group\Events\GroupDeletedEvent; use OCP\IAppConfig; @@ -82,34 +79,14 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(CircleDestroyedEvent::class, CircleDestroyedEventListener::class); $context->registerEventListener(NodeRenamedEvent::class, NodeRenamedListener::class); - $context->registerService('GroupAppFolder', function (ContainerInterface $c): Folder { - /** @var IRootFolder $rootFolder */ - $rootFolder = $c->get(IRootFolder::class); - - return new LazyFolder($rootFolder, function () use ($rootFolder): Folder { - try { - /** @var Folder $folder */ - $folder = $rootFolder->get('__groupfolders'); - - return $folder; - } catch (NotFoundException) { - return $rootFolder->newFolder('__groupfolders'); - } - }, [ - 'path' => '/__groupfolders' - ]); - }); - $context->registerService(MountProvider::class, function (ContainerInterface $c): MountProvider { - $rootProvider = fn (): Folder => $c->get('GroupAppFolder'); /** @var IAppConfig $config */ $config = $c->get(IAppConfig::class); - $allowRootShare = $config->getValueString('groupfolders', 'allow_root_share', 'true') === 'true'; - $enableEncryption = $config->getValueString('groupfolders', 'enable_encryption', 'false') === 'true'; + $allowRootShare = $config->getValueBool('groupfolders', 'allow_root_share', true); + $enableEncryption = $config->getValueBool('groupfolders', 'enable_encryption'); return new MountProvider( $c->get(FolderManager::class), - $rootProvider, $c->get(ACLManagerFactory::class), $c->get(IUserSession::class), $c->get(IRequest::class), diff --git a/lib/CacheListener.php b/lib/CacheListener.php index fb3c9c264..04d5d6394 100644 --- a/lib/CacheListener.php +++ b/lib/CacheListener.php @@ -7,12 +7,12 @@ */ namespace OCA\GroupFolders; +use OC\Files\Storage\Wrapper\Jail; use OCA\GroupFolders\Mount\GroupFolderStorage; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Cache\CacheEntryInsertedEvent; use OCP\Files\Cache\CacheEntryUpdatedEvent; use OCP\Files\Cache\ICacheEvent; -use RuntimeException; class CacheListener { public function __construct( @@ -26,17 +26,15 @@ public function listen(): void { } public function onCacheEvent(ICacheEvent $event): void { - if (!$event->getStorage()->instanceOfStorage(GroupFolderStorage::class)) { + $storage = $event->getStorage(); + if (!$storage->instanceOfStorage(GroupFolderStorage::class)) { return; } - - $jailedPath = preg_replace('/^__groupfolders\/\d+\//', '', $event->getPath()); - if ($jailedPath === null) { - throw new RuntimeException('Failed to build jailed path'); + if (!$storage->instanceOfStorage(Jail::class)) { + return; } - - if ($jailedPath !== $event->getPath()) { - $event->setPath($jailedPath); + if ($path = $storage->getJailedPath($event->getPath())) { + $event->setPath($path); } } } diff --git a/lib/Command/ACL.php b/lib/Command/ACL.php index 8ddaee75f..1944dc1d4 100644 --- a/lib/Command/ACL.php +++ b/lib/Command/ACL.php @@ -12,9 +12,9 @@ use OCA\GroupFolders\ACL\Rule; use OCA\GroupFolders\ACL\RuleManager; use OCA\GroupFolders\ACL\UserMapping\UserMapping; -use OCA\GroupFolders\Folder\FolderDefinition; use OCA\GroupFolders\Folder\FolderDefinitionWithPermissions; use OCA\GroupFolders\Folder\FolderManager; +use OCA\GroupFolders\Folder\FolderWithMappingsAndCache; use OCA\GroupFolders\Mount\FolderStorageManager; use OCA\GroupFolders\Mount\MountProvider; use OCP\Constants; @@ -77,13 +77,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int return -1; } - $jailPath = $this->mountProvider->getJailPath($folder->id); $path = $input->getArgument('path'); $aclManager = $this->aclManagerFactory->getACLManager($user); if ($this->folderManager->getFolderPermissionsForUser($user, $folder->id) === 0) { $permissions = 0; } else { - $permissions = $aclManager->getACLPermissionsForPath($folder->storageId, $jailPath . rtrim('/' . $path, '/')); + $permissions = $aclManager->getACLPermissionsForPath($folder->storageId, $folder->rootCacheEntry->getPath() . rtrim('/' . $path, '/')); } $permissionString = Rule::formatRulePermissions(Constants::PERMISSION_ALL, $permissions); $output->writeln($permissionString); @@ -188,13 +187,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 0; } - private function printPermissions(InputInterface $input, OutputInterface $output, FolderDefinition $folder): void { - $jailPath = $this->mountProvider->getJailPath($folder->id); + private function printPermissions(InputInterface $input, OutputInterface $output, FolderWithMappingsAndCache $folder): void { + $rootPath = $folder->rootCacheEntry->getPath(); $rules = $this->ruleManager->getAllRulesForPrefix( $this->rootFolder->getMountPoint()->getNumericStorageId(), - $jailPath + $rootPath ); - $jailPathLength = strlen($jailPath) + 1; + $jailPathLength = strlen($rootPath) + 1; $outputFormat = $input->getOption('output'); switch ($outputFormat) { diff --git a/lib/Mount/CacheRootPermissionsMask.php b/lib/Mount/CacheRootPermissionsMask.php index 3a715a2f6..80e9d12a7 100644 --- a/lib/Mount/CacheRootPermissionsMask.php +++ b/lib/Mount/CacheRootPermissionsMask.php @@ -16,13 +16,13 @@ class CacheRootPermissionsMask extends CacheWrapper { public function __construct( ICache $cache, private readonly int $mask, + private readonly int $rootId, ) { parent::__construct($cache); } protected function formatCacheEntry($entry): ICacheEntry|false { - $path = $entry->getPath(); - $isRoot = $path === '' || (str_starts_with($path, '__groupfolders') && count(explode('/', $path)) === 2); + $isRoot = $entry->getId() === $this->rootId; if (isset($entry['permissions']) && $isRoot) { $entry['scan_permissions'] = $entry['permissions']; $entry['permissions'] &= $this->mask; diff --git a/lib/Mount/GroupMountPoint.php b/lib/Mount/GroupMountPoint.php index 64caac96d..fc98ded24 100644 --- a/lib/Mount/GroupMountPoint.php +++ b/lib/Mount/GroupMountPoint.php @@ -10,6 +10,7 @@ use OC\Files\Mount\MountPoint; use OC\Files\Storage\Storage; +use OC\Files\Storage\Wrapper\Jail; use OCA\GroupFolders\Folder\FolderDefinition; use OCP\Files\Mount\IShareOwnerlessMount; use OCP\Files\Mount\ISystemMountPoint; @@ -45,7 +46,12 @@ public function getFolder(): FolderDefinition { } public function getSourcePath(): string { - // todo - return '/__groupfolders/' . $this->getFolderId(); + $storage = $this->storage; + if ($storage && $storage->instanceOfStorage(Jail::class)) { + /** @var Jail $storage */ + return $storage->getUnJailedPath(''); + } else { + return ''; + } } } diff --git a/lib/Mount/MountProvider.php b/lib/Mount/MountProvider.php index 0d11cb041..5c3b831df 100644 --- a/lib/Mount/MountProvider.php +++ b/lib/Mount/MountProvider.php @@ -33,7 +33,6 @@ class MountProvider implements IMountProvider { public function __construct( private readonly FolderManager $folderManager, - private readonly \Closure $rootProvider, private readonly ACLManagerFactory $aclManagerFactory, private readonly IUserSession $userSession, private readonly IRequest $request, @@ -110,7 +109,7 @@ private function getCurrentUID(): ?string { $user = $this->userSession->getUser(); - return $user ? $user->getUID() : null; + return $user?->getUID(); } public function getMount( @@ -123,14 +122,8 @@ public function getMount( ): ?IMountPoint { $cacheEntry = $folder->rootCacheEntry; - $storage = $this->getRootFolder()->getStorage(); - - $storage->setOwner($user?->getUID()); - - $rootPath = $this->getJailPath($folder->id); - if ($aclManager && $folder->acl && $user) { - $aclRootPermissions = $aclManager->getPermissionsForPathFromRules($rootPath, $rootRules); + $aclRootPermissions = $aclManager->getPermissionsForPathFromRules($cacheEntry->getPath(), $rootRules); $cacheEntry['permissions'] &= $aclRootPermissions; } @@ -145,6 +138,7 @@ public function getMount( $maskedStore = new RootPermissionsMask([ 'storage' => $maskedStore, 'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE, + 'folder' => $folder, ]); } @@ -231,6 +225,11 @@ public function getGroupFolderStorage( } else { $baseStorage = $this->folderStorageManager->getBaseStorageForFolder($folder->id, $folder, null, false, $type); } + + if ($user) { + $baseStorage->setOwner($user->getUID()); + } + if ($this->enableEncryption) { $quotaStorage = new GroupFolderStorage([ 'storage' => $baseStorage, @@ -254,19 +253,6 @@ public function getGroupFolderStorage( return $quotaStorage; } - public function getJailPath(int $folderId): string { - return $this->getRootFolder()->getInternalPath() . '/' . $folderId; - } - - private function getRootFolder(): Folder { - if (is_null($this->root)) { - $rootProvider = $this->rootProvider; - $this->root = $rootProvider(); - } - - return $this->root; - } - /** * @param string[] $mountPoints * @return string[] An array of paths. diff --git a/lib/Mount/RootPermissionsMask.php b/lib/Mount/RootPermissionsMask.php index ab3eb2d71..17de6e8bb 100644 --- a/lib/Mount/RootPermissionsMask.php +++ b/lib/Mount/RootPermissionsMask.php @@ -9,6 +9,7 @@ namespace OCA\GroupFolders\Mount; use OC\Files\Storage\Wrapper\Wrapper; +use OCA\GroupFolders\Folder\FolderDefinition; use OCP\Constants; use OCP\Files\Cache\ICache; use OCP\Files\Storage\IStorage; @@ -21,6 +22,7 @@ class RootPermissionsMask extends Wrapper { * the permissions bits we want to keep */ private readonly int $mask; + private readonly FolderDefinition $folder; /** * @param array $arguments ['storage' => $storage, 'mask' => $mask] @@ -31,6 +33,7 @@ class RootPermissionsMask extends Wrapper { public function __construct($arguments) { parent::__construct($arguments); $this->mask = $arguments['mask']; + $this->folder = $arguments['folder']; } private function checkMask(int $permissions): bool { @@ -95,6 +98,6 @@ public function getCache(string $path = '', ?IStorage $storage = null): ICache { $sourceCache = parent::getCache($path, $storage); - return new CacheRootPermissionsMask($sourceCache, $this->mask); + return new CacheRootPermissionsMask($sourceCache, $this->mask, $this->folder->rootId); } }