diff options
author | Robin Appelman <robin@icewind.nl> | 2018-11-23 20:11:55 +0300 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2018-11-25 03:39:54 +0300 |
commit | 36cfd40e944e678b2e621210baa3a9c83e69c5b2 (patch) | |
tree | 0e80c6aa388cc938745e096eceb8ac10c313e528 | |
parent | 8fc88d86097d75327a30654a7b3f0b10a814990a (diff) |
add console commands to configure group folders
Signed-off-by: Robin Appelman <robin@icewind.nl>
-rw-r--r-- | appinfo/info.xml | 8 | ||||
-rw-r--r-- | lib/Command/Create.php | 53 | ||||
-rw-r--r-- | lib/Command/Delete.php | 71 | ||||
-rw-r--r-- | lib/Command/Group.php | 110 | ||||
-rw-r--r-- | lib/Command/ListCommand.php | 95 | ||||
-rw-r--r-- | lib/Command/Quota.php | 68 | ||||
-rw-r--r-- | lib/Command/Rename.php | 60 | ||||
-rw-r--r-- | lib/Folder/FolderManager.php | 4 |
8 files changed, 466 insertions, 3 deletions
diff --git a/appinfo/info.xml b/appinfo/info.xml index 20ec8ac4..939ca086 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -29,11 +29,17 @@ Note: encrypting the contents of group folders is currently not supported.]]></d <screenshot>https://raw.githubusercontent.com/nextcloud/groupfolders/master/screenshots/permissions.png</screenshot> <dependencies> - <nextcloud min-version="13" max-version="15"/> + <nextcloud min-version="13" max-version="16"/> </dependencies> <commands> <command>OCA\GroupFolders\Command\ExpireGroupVersions</command> + <command>OCA\GroupFolders\Command\ListCommand</command> + <command>OCA\GroupFolders\Command\Quota</command> + <command>OCA\GroupFolders\Command\Group</command> + <command>OCA\GroupFolders\Command\Create</command> + <command>OCA\GroupFolders\Command\Rename</command> + <command>OCA\GroupFolders\Command\Delete</command> </commands> <background-jobs> diff --git a/lib/Command/Create.php b/lib/Command/Create.php new file mode 100644 index 00000000..a0fc4d43 --- /dev/null +++ b/lib/Command/Create.php @@ -0,0 +1,53 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCP\Files\IRootFolder; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Create extends Base { + private $folderManager; + private $rootFolder; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + } + + protected function configure() { + $this + ->setName('groupfolders:create') + ->setDescription('Create a new group folder') + ->addArgument('name', InputArgument::REQUIRED, 'Name of the new folder'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $this->folderManager->createFolder($input->getArgument('name')); + } +} diff --git a/lib/Command/Delete.php b/lib/Command/Delete.php new file mode 100644 index 00000000..ef3f13e8 --- /dev/null +++ b/lib/Command/Delete.php @@ -0,0 +1,71 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCA\GroupFolders\Mount\MountProvider; +use OCP\Files\IRootFolder; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; + +class Delete extends Base { + private $folderManager; + private $rootFolder; + private $mountProvider; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder, MountProvider $mountProvider) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + $this->mountProvider = $mountProvider; + } + + protected function configure() { + $this + ->setName('groupfolders:delete') + ->setDescription('Delete group folder') + ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to rename') + ->addOption('force', 'f', InputOption::VALUE_NONE, 'Skip confirmation'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $folderId = $input->getArgument('folder_id'); + $folder = $this->folderManager->getFolder($folderId, $this->rootFolder->getMountPoint()->getNumericStorageId()); + if ($folder) { + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Are you sure you want to delete the group folder' . $folder['mount_point'] . ' and all files within, this can not be undone (y/N).', false); + if ($input->getOption('force') || $helper->ask($input, $output, $question)) { + $folder = $this->mountProvider->getFolder($folderId); + $this->folderManager->removeFolder($folderId); + $folder->delete(); + } + } else { + $output->writeln('<error>Folder not found: ' . $folderId . '</error>'); + return -1; + } + } +} diff --git a/lib/Command/Group.php b/lib/Command/Group.php new file mode 100644 index 00000000..c795a04b --- /dev/null +++ b/lib/Command/Group.php @@ -0,0 +1,110 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCP\Constants; +use OCP\Files\IRootFolder; +use OCP\IGroupManager; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class Group extends Base { + const PERMISSION_VALUES = [ + 'read' => Constants::PERMISSION_READ, + 'write' => Constants::PERMISSION_UPDATE | Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE, + 'share' => Constants::PERMISSION_SHARE + ]; + + + private $folderManager; + private $rootFolder; + private $groupManager; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder, IGroupManager $groupManager) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + $this->groupManager = $groupManager; + } + + protected function configure() { + $this + ->setName('groupfolders:group') + ->setDescription('Edit the groups that have access to a group folder') + ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure') + ->addArgument('group', InputArgument::REQUIRED, 'The group to configure') + ->addArgument('permissions', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'The permissions to set for the group, leave empty for read only') + ->addOption('delete', 'd', InputOption::VALUE_NONE, 'Remove access for the group'); + + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $folderId = $input->getArgument('folder_id'); + $folder = $this->folderManager->getFolder($folderId, $this->rootFolder->getMountPoint()->getNumericStorageId()); + if ($folder) { + $groupString = $input->getArgument('group'); + $group = $this->groupManager->get($groupString); + if ($group) { + if ($input->getOption('delete')) { + $this->folderManager->removeApplicableGroup($folderId, $groupString); + } else { + $permissionsString = $input->getArgument('permissions'); + $permissions = $this->getNewPermissions($permissionsString); + if ($permissions) { + if (!isset($folder['groups'][$groupString])) { + $this->folderManager->addApplicableGroup($folderId, $groupString); + } + $this->folderManager->setGroupPermissions($folderId, $groupString, $permissions); + return 0; + } else { + $output->writeln('<error>Unable to parse permissions input: ' . implode(' ', $permissionsString) . '</error>'); + return -1; + } + } + } else { + $output->writeln('<error>group not found: ' . $groupString . '</error>'); + return -1; + } + } else { + $output->writeln('<error>Folder not found: ' . $folderId . '</error>'); + return -1; + } + } + + private function getNewPermissions(array $input) { + $permissions = 1; + foreach ($input as $permissionsString) { + if (isset(self::PERMISSION_VALUES[$permissionsString])) { + $permissions |= self::PERMISSION_VALUES[$permissionsString]; + } else { + return 0; + } + } + return $permissions; + } +} diff --git a/lib/Command/ListCommand.php b/lib/Command/ListCommand.php new file mode 100644 index 00000000..60d78143 --- /dev/null +++ b/lib/Command/ListCommand.php @@ -0,0 +1,95 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCP\Constants; +use OCP\Files\IRootFolder; +use Symfony\Component\Console\Helper\Table; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class ListCommand extends Base { + const PERMISSION_NAMES = [ + Constants::PERMISSION_READ => 'read', + Constants::PERMISSION_UPDATE => 'write', + Constants::PERMISSION_SHARE => 'share' + ]; + + private $folderManager; + private $rootFolder; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + } + + protected function configure() { + $this + ->setName('groupfolders:list') + ->setDescription('List the configured group folders'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $folders = $this->folderManager->getAllFoldersWithSize($this->rootFolder->getMountPoint()->getNumericStorageId()); + + $outputType = $input->getOption('output'); + if (count($folders) === 0) { + if ($outputType === self::OUTPUT_FORMAT_JSON || $outputType === self::OUTPUT_FORMAT_JSON_PRETTY) { + $output->writeln('[]'); + } else { + $output->writeln("<info>No folders configured</info>"); + } + return; + } + + if ($outputType === self::OUTPUT_FORMAT_JSON || $outputType === self::OUTPUT_FORMAT_JSON_PRETTY) { + $this->writeArrayInOutputFormat($input, $output, $folders); + } else { + $table = new Table($output); + $table->setHeaders(['Folder Id', 'Name', 'Groups', 'Quota', 'Size']); + $table->setRows(array_map(function ($folder) { + $folder['size'] = \OC_Helper::humanFileSize($folder['size']); + $folder['quota'] = ($folder['quota'] > 0) ? \OC_Helper::humanFileSize($folder['quota']) : 'Unlimited'; + $groupStrings = array_map(function (string $groupId, int $permissions) { + return $groupId . ': ' . $this->permissionsToString($permissions); + }, array_keys($folder['groups']), array_values($folder['groups'])); + $folder['groups'] = implode("\n", $groupStrings); + return $folder; + }, $folders)); + $table->render(); + } + } + + private function permissionsToString(int $permissions): string { + if ($permissions === 0) { + return 'none'; + } + return implode(', ', array_filter(self::PERMISSION_NAMES, function ($possiblePermission) use ($permissions) { + return $possiblePermission & $permissions; + }, ARRAY_FILTER_USE_KEY)); + } +} diff --git a/lib/Command/Quota.php b/lib/Command/Quota.php new file mode 100644 index 00000000..07db2e1b --- /dev/null +++ b/lib/Command/Quota.php @@ -0,0 +1,68 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCP\Files\IRootFolder; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Quota extends Base { + private $folderManager; + private $rootFolder; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + } + + protected function configure() { + $this + ->setName('groupfolders:quota') + ->setDescription('Edit the quota of a configured group folder') + ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to configure') + ->addArgument('quota', InputArgument::REQUIRED, 'New value for the quota of the folder'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $folderId = $input->getArgument('folder_id'); + $folder = $this->folderManager->getFolder($folderId, $this->rootFolder->getMountPoint()->getNumericStorageId()); + if ($folder) { + $quotaString = $input->getArgument('quota'); + $quota = \OC_Helper::computerFileSize($quotaString); + if ($quota) { + $this->folderManager->setFolderQuota($folderId, $quota); + } else { + $output->writeln('<error>Unable to parse quota input: ' . $quotaString . '</error>'); + return -1; + } + } else { + $output->writeln('<error>Folder not found: ' . $folderId . '</error>'); + return -1; + } + } +} diff --git a/lib/Command/Rename.php b/lib/Command/Rename.php new file mode 100644 index 00000000..c402c9bc --- /dev/null +++ b/lib/Command/Rename.php @@ -0,0 +1,60 @@ +<?php declare(strict_types=1); +/** + * @copyright Copyright (c) 2018 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\Command; + +use OC\Core\Command\Base; +use OCA\GroupFolders\Folder\FolderManager; +use OCP\Files\IRootFolder; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Rename extends Base { + private $folderManager; + private $rootFolder; + + public function __construct(FolderManager $folderManager, IRootFolder $rootFolder) { + parent::__construct(); + $this->folderManager = $folderManager; + $this->rootFolder = $rootFolder; + } + + protected function configure() { + $this + ->setName('groupfolders:rename') + ->setDescription('Rename group folder') + ->addArgument('folder_id', InputArgument::REQUIRED, 'Id of the folder to rename') + ->addArgument('name', InputArgument::REQUIRED, 'New value name of the folder'); + parent::configure(); + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $folderId = $input->getArgument('folder_id'); + $folder = $this->folderManager->getFolder($folderId, $this->rootFolder->getMountPoint()->getNumericStorageId()); + if ($folder) { + $this->folderManager->renameFolder($folderId, $input->getArgument('name')); + } else { + $output->writeln('<error>Folder not found: ' . $folderId . '</error>'); + return -1; + } + } +} diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index 47de8b48..17b4aa94 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -112,13 +112,13 @@ class FolderManager { $row = $query->execute()->fetch(); - return [ + return $row ? [ 'id' => $id, 'mount_point' => $row['mount_point'], 'groups' => isset($applicableMap[$id]) ? $applicableMap[$id] : [], 'quota' => $row['quota'], 'size' => $row['size'] ? $row['size'] : 0 - ]; + ] : false; } private function getAllApplicable() { |