diff options
author | Robin Appelman <robin@icewind.nl> | 2022-06-03 19:04:10 +0300 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2022-06-07 20:24:09 +0300 |
commit | 7a958cd17ab840e5e4493b3ee5d96ebba2c42d91 (patch) | |
tree | dd41da818bc3a146295be404716d4739836a2140 | |
parent | c3486360bceae366331f7def83a40f4d8284096e (diff) |
allow disabling sharing of groupfolder rootbackport/2013/stable23
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r-- | lib/AppInfo/Application.php | 5 | ||||
-rw-r--r-- | lib/Mount/CacheRootPermissionsMask.php | 46 | ||||
-rw-r--r-- | lib/Mount/MountProvider.php | 13 | ||||
-rw-r--r-- | lib/Mount/RootPermissionsMask.php | 110 |
4 files changed, 172 insertions, 2 deletions
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 1d6a7df6..55d5c268 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -74,6 +74,8 @@ class Application extends App implements IBootstrap { $rootProvider = function () use ($c) { return $c->get('GroupAppFolder'); }; + $config = $c->get(IConfig::class); + $allowRootShare = $config->getAppValue('groupfolders', 'allow_root_share', 'true') === 'true'; return new MountProvider( $c->getServer()->getGroupManager(), @@ -84,7 +86,8 @@ class Application extends App implements IBootstrap { $c->get(IRequest::class), $c->get(ISession::class), $c->get(IMountProviderCollection::class), - $c->get(IDBConnection::class) + $c->get(IDBConnection::class), + $allowRootShare ); }); diff --git a/lib/Mount/CacheRootPermissionsMask.php b/lib/Mount/CacheRootPermissionsMask.php new file mode 100644 index 00000000..2c0b83b6 --- /dev/null +++ b/lib/Mount/CacheRootPermissionsMask.php @@ -0,0 +1,46 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @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\GroupFolders\Mount; + +use OC\Files\Cache\Wrapper\CacheWrapper; +use OCP\Files\Cache\ICache; + +class CacheRootPermissionsMask extends CacheWrapper { + protected int $mask; + + public function __construct(ICache $cache, int $mask) { + parent::__construct($cache); + $this->mask = $mask; + } + + protected function formatCacheEntry($entry) { + $path = $entry['path']; + $isRoot = $path === '' || (strpos($path, '__groupfolders') === 0 && count(explode('/', $path)) === 2); + if (isset($entry['permissions']) && $isRoot) { + $entry['scan_permissions'] = $entry['permissions']; + $entry['permissions'] &= $this->mask; + } + return $entry; + } +} diff --git a/lib/Mount/MountProvider.php b/lib/Mount/MountProvider.php index e4905282..94400031 100644 --- a/lib/Mount/MountProvider.php +++ b/lib/Mount/MountProvider.php @@ -26,6 +26,7 @@ use OC\Files\Storage\Wrapper\PermissionsMask; use OCA\GroupFolders\ACL\ACLManagerFactory; use OCA\GroupFolders\ACL\ACLStorageWrapper; use OCA\GroupFolders\Folder\FolderManager; +use OCP\Constants; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Config\IMountProvider; use OCP\Files\Config\IMountProviderCollection; @@ -66,6 +67,7 @@ class MountProvider implements IMountProvider { private $mountProviderCollection; private $connection; + private bool $allowRootShare; public function __construct( IGroupManager $groupProvider, @@ -76,7 +78,8 @@ class MountProvider implements IMountProvider { IRequest $request, ISession $session, IMountProviderCollection $mountProviderCollection, - IDBConnection $connection + IDBConnection $connection, + bool $allowRootShare ) { $this->groupProvider = $groupProvider; $this->folderManager = $folderManager; @@ -87,6 +90,7 @@ class MountProvider implements IMountProvider { $this->session = $session; $this->mountProviderCollection = $mountProviderCollection; $this->connection = $connection; + $this->allowRootShare = $allowRootShare; } /** @@ -198,6 +202,13 @@ class MountProvider implements IMountProvider { 'mask' => $permissions ]); + if (!$this->allowRootShare) { + $maskedStore = new RootPermissionsMask([ + 'storage' => $maskedStore, + 'mask' => Constants::PERMISSION_ALL - Constants::PERMISSION_SHARE, + ]); + } + return new GroupMountPoint( $id, $maskedStore, diff --git a/lib/Mount/RootPermissionsMask.php b/lib/Mount/RootPermissionsMask.php new file mode 100644 index 00000000..6f5a9fe6 --- /dev/null +++ b/lib/Mount/RootPermissionsMask.php @@ -0,0 +1,110 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2022 Robin Appelman <robin@icewind.nl> + * + * @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\GroupFolders\Mount; + +use OC\Files\Storage\Wrapper\Wrapper; +use OCP\Constants; + +/** + * Permissions mask that only masks the root of the storage + */ +class RootPermissionsMask extends Wrapper { + /** + * @var int the permissions bits we want to keep + */ + private $mask; + + /** + * @param array $arguments ['storage' => $storage, 'mask' => $mask] + * + * $storage: The storage the permissions mask should be applied on + * $mask: The permission bits that should be kept, a combination of the \OCP\Constant::PERMISSION_ constants + */ + public function __construct($arguments) { + parent::__construct($arguments); + $this->mask = $arguments['mask']; + } + + private function checkMask($permissions) { + return ($this->mask & $permissions) === $permissions; + } + + public function isUpdatable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_UPDATE) and parent::isUpdatable($path); + } else { + return parent::isUpdatable($path); + } + } + + public function isCreatable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_CREATE) and parent::isCreatable($path); + } else { + return parent::isCreatable($path); + } + } + + public function isDeletable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_DELETE) and parent::isDeletable($path); + } else { + return parent::isDeletable($path); + } + } + + public function isSharable($path) { + if ($path === '') { + return $this->checkMask(Constants::PERMISSION_SHARE) and parent::isSharable($path); + } else { + return parent::isSharable($path); + } + } + + public function getPermissions($path) { + if ($path === '') { + return $this->storage->getPermissions($path) & $this->mask; + } else { + return $this->storage->getPermissions($path); + } + } + + public function getMetaData($path) { + $data = parent::getMetaData($path); + + if ($data && $path === '' && isset($data['permissions'])) { + $data['scan_permissions'] = $data['scan_permissions'] ?? $data['permissions']; + $data['permissions'] &= $this->mask; + } + return $data; + } + + public function getCache($path = '', $storage = null) { + if (!$storage) { + $storage = $this; + } + $sourceCache = parent::getCache($path, $storage); + return new CacheRootPermissionsMask($sourceCache, $this->mask); + } +} |