diff --git a/apps/workflowengine/appinfo/info.xml b/apps/workflowengine/appinfo/info.xml index a2f216b295..ddb2053828 100644 --- a/apps/workflowengine/appinfo/info.xml +++ b/apps/workflowengine/appinfo/info.xml @@ -2,11 +2,13 @@ workflowengine - Files workflow engine - Files workflow engine - Files workflow engine + Nextcloud workflow engine + Nextcloud workflow engine + Nextcloud workflow engine 1.8.0 agpl + Arthur Schiwon + Julius Härtl Morris Jobke WorkflowEngine @@ -23,6 +25,16 @@ + + + OCA\WorkflowEngine\Migration\PopulateNewlyIntroducedDatabaseFields + + + + + OCA\WorkflowEngine\Command\Index + + OCA\WorkflowEngine\Settings\Section diff --git a/apps/workflowengine/composer/composer/autoload_classmap.php b/apps/workflowengine/composer/composer/autoload_classmap.php index 86a7737547..269a41a96b 100644 --- a/apps/workflowengine/composer/composer/autoload_classmap.php +++ b/apps/workflowengine/composer/composer/autoload_classmap.php @@ -17,6 +17,7 @@ return array( 'OCA\\WorkflowEngine\\Check\\RequestURL' => $baseDir . '/../lib/Check/RequestURL.php', 'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => $baseDir . '/../lib/Check/RequestUserAgent.php', 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => $baseDir . '/../lib/Check/UserGroupMembership.php', + 'OCA\\WorkflowEngine\\Command\\Index' => $baseDir . '/../lib/Command/Index.php', 'OCA\\WorkflowEngine\\Controller\\FlowOperations' => $baseDir . '/../lib/Controller/FlowOperations.php', 'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => $baseDir . '/../lib/Controller/GlobalWorkflowsController.php', 'OCA\\WorkflowEngine\\Controller\\RequestTime' => $baseDir . '/../lib/Controller/RequestTime.php', @@ -24,6 +25,7 @@ return array( 'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => $baseDir . '/../lib/Entity/GenericEntityEmitterEvent.php', 'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => $baseDir . '/../lib/Entity/IEntityEmitterEvent.php', 'OCA\\WorkflowEngine\\Manager' => $baseDir . '/../lib/Manager.php', + 'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => $baseDir . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php', 'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => $baseDir . '/../lib/Migration/Version2019Date20190808074233.php', 'OCA\\WorkflowEngine\\Settings\\Admin' => $baseDir . '/../lib/Settings/Admin.php', 'OCA\\WorkflowEngine\\Settings\\Section' => $baseDir . '/../lib/Settings/Section.php', diff --git a/apps/workflowengine/composer/composer/autoload_static.php b/apps/workflowengine/composer/composer/autoload_static.php index d13578448c..eed3f208f8 100644 --- a/apps/workflowengine/composer/composer/autoload_static.php +++ b/apps/workflowengine/composer/composer/autoload_static.php @@ -32,6 +32,7 @@ class ComposerStaticInitWorkflowEngine 'OCA\\WorkflowEngine\\Check\\RequestURL' => __DIR__ . '/..' . '/../lib/Check/RequestURL.php', 'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => __DIR__ . '/..' . '/../lib/Check/RequestUserAgent.php', 'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => __DIR__ . '/..' . '/../lib/Check/UserGroupMembership.php', + 'OCA\\WorkflowEngine\\Command\\Index' => __DIR__ . '/..' . '/../lib/Command/Index.php', 'OCA\\WorkflowEngine\\Controller\\FlowOperations' => __DIR__ . '/..' . '/../lib/Controller/FlowOperations.php', 'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/GlobalWorkflowsController.php', 'OCA\\WorkflowEngine\\Controller\\RequestTime' => __DIR__ . '/..' . '/../lib/Controller/RequestTime.php', @@ -39,6 +40,7 @@ class ComposerStaticInitWorkflowEngine 'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/GenericEntityEmitterEvent.php', 'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/IEntityEmitterEvent.php', 'OCA\\WorkflowEngine\\Manager' => __DIR__ . '/..' . '/../lib/Manager.php', + 'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => __DIR__ . '/..' . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php', 'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => __DIR__ . '/..' . '/../lib/Migration/Version2019Date20190808074233.php', 'OCA\\WorkflowEngine\\Settings\\Admin' => __DIR__ . '/..' . '/../lib/Settings/Admin.php', 'OCA\\WorkflowEngine\\Settings\\Section' => __DIR__ . '/..' . '/../lib/Settings/Section.php', diff --git a/apps/workflowengine/lib/Command/Index.php b/apps/workflowengine/lib/Command/Index.php new file mode 100644 index 0000000000..8098bc5d5e --- /dev/null +++ b/apps/workflowengine/lib/Command/Index.php @@ -0,0 +1,77 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +namespace OCA\WorkflowEngine\Command; + +use OCA\WorkflowEngine\Manager; +use OCP\WorkflowEngine\IManager; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +class Index extends Command { + + /** @var Manager */ + private $manager; + + public function __construct(Manager $manager) { + $this->manager = $manager; + parent::__construct(); + } + + protected function configure() { + $this + ->setName('workflows:list') + ->setDescription('Lists configured workflows') + ->addArgument( + 'scope', + InputArgument::OPTIONAL, + 'Lists workflows for "admin", "user"', + 'admin' + ) + ->addArgument( + 'scopeId', + InputArgument::OPTIONAL, + 'User IDs when the scope is "user"', + null + ); + } + + protected function mappedScope(string $scope): int { + static $scopes = [ + 'admin' => IManager::SCOPE_ADMIN, + 'user' => IManager::SCOPE_USER, + ]; + return $scopes[$scope] ?? -1; + } + + protected function execute(InputInterface $input, OutputInterface $output) { + $ops = $this->manager->getAllOperations( + $this->mappedScope($input->getArgument('scope')), + $input->getArgument('scopeId') + ); + $output->writeln(\json_encode($ops)); + } +} diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php index 3a382f20dc..3bfedfbfbf 100644 --- a/apps/workflowengine/lib/Manager.php +++ b/apps/workflowengine/lib/Manager.php @@ -31,6 +31,7 @@ use OCP\IDBConnection; use OCP\IL10N; use OCP\ILogger; use OCP\IServerContainer; +use OCP\IUserSession; use OCP\WorkflowEngine\ICheck; use OCP\WorkflowEngine\IEntity; use OCP\WorkflowEngine\IEntityAware; @@ -73,6 +74,8 @@ class Manager implements IManager, IEntityAware { /** @var ILogger */ protected $logger; + /** @var IUserSession */ + protected $session; /** * @param IDBConnection $connection @@ -84,13 +87,15 @@ class Manager implements IManager, IEntityAware { IServerContainer $container, IL10N $l, EventDispatcherInterface $eventDispatcher, - ILogger $logger + ILogger $logger, + IUserSession $session ) { $this->connection = $connection; $this->container = $container; $this->l = $l; $this->eventDispatcher = $eventDispatcher; $this->logger = $logger; + $this->session = $session; } /** @@ -155,14 +160,33 @@ class Manager implements IManager, IEntityAware { throw new \UnexpectedValueException($this->l->t('Check %s is invalid or does not exist', $check['class'])); } } + public function getAllOperations(int $scope = IManager::SCOPE_ADMIN, string $scopeId = null): array { + if(!in_array($scope, [IManager::SCOPE_ADMIN, IManager::SCOPE_USER])) { + throw new \InvalidArgumentException('Provided value for scope is not supported'); + } + if($scope === IManager::SCOPE_USER && $scopeId === null) { + $user = $this->session->getUser(); + if($user === null) { + throw new \InvalidArgumentException('No user ID was provided'); + } + $scopeId = $user->getUID(); + } - public function getAllOperations(): array { $this->operations = []; $query = $this->connection->getQueryBuilder(); - $query->select('*') - ->from('flow_operations'); + $query->select('o.*') + ->from('flow_operations', 'o') + ->leftJoin('o', 'flow_operations_scope', 's', $query->expr()->eq('o.id', 's.operation_id')) + ->where($query->expr()->eq('s.type', $query->createParameter('scope'))); + + if($scope === IManager::SCOPE_USER) { + $query->andWhere($query->expr()->eq('s.value', $query->createParameter('scopeId'))); + } + + $query->setParameters(['scope' => $scope, 'scopeId' => $scopeId]); + $result = $query->execute(); while ($row = $result->fetch()) { @@ -175,6 +199,7 @@ class Manager implements IManager, IEntityAware { return $this->operations; } + /** * @param string $class * @return array[] diff --git a/apps/workflowengine/lib/Migration/PopulateNewlyIntroducedDatabaseFields.php b/apps/workflowengine/lib/Migration/PopulateNewlyIntroducedDatabaseFields.php new file mode 100644 index 0000000000..43595d1c7c --- /dev/null +++ b/apps/workflowengine/lib/Migration/PopulateNewlyIntroducedDatabaseFields.php @@ -0,0 +1,76 @@ + + * + * @author Arthur Schiwon + * + * @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 . + * + */ + +namespace OCA\WorkflowEngine\Migration; + +use Doctrine\DBAL\Driver\Statement; +use OCP\IDBConnection; +use OCP\Migration\IOutput; +use OCP\Migration\IRepairStep; +use OCP\WorkflowEngine\IManager; + +class PopulateNewlyIntroducedDatabaseFields implements IRepairStep { + + /** @var IDBConnection */ + private $dbc; + + public function __construct(IDBConnection $dbc) { + $this->dbc = $dbc; + } + + public function getName() { + return 'Populating added database structures for workflows'; + } + + public function run(IOutput $output) { + $result = $this->getIdsWithoutScope(); + + $this->populateScopeTable($result); + + $result->closeCursor(); + } + + protected function populateScopeTable(Statement $ids): void { + $qb = $this->dbc->getQueryBuilder(); + + $insertQuery = $qb->insert('flow_operations_scope'); + while($id = $ids->fetchColumn(0)) { + $insertQuery->values(['operation_id' => $qb->createNamedParameter($id), 'type' => IManager::SCOPE_ADMIN]); + } + $insertQuery->execute(); + } + + protected function getIdsWithoutScope(): Statement { + $qb = $this->dbc->getQueryBuilder(); + $selectQuery = $qb->select('o.id') + ->from('flow_operations', 'o') + ->leftJoin('o', 'flow_operations_scope', 's', $qb->expr()->eq('o.id', 's.operation_id')) + ->where($qb->expr()->isNull('s.operation_id')); + // The left join operation is not necessary, usually, but it's a safe-guard + // in case the repair step is executed multiple times for whatever reason. + + return $selectQuery->execute(); + } + +} diff --git a/lib/public/WorkflowEngine/IManager.php b/lib/public/WorkflowEngine/IManager.php index 33a1dd1bb6..c05459e1fb 100644 --- a/lib/public/WorkflowEngine/IManager.php +++ b/lib/public/WorkflowEngine/IManager.php @@ -33,6 +33,10 @@ use OCP\Files\Storage\IStorage; * @since 9.1 */ interface IManager { + + const SCOPE_ADMIN = 0; + const SCOPE_USER = 1; + /** * @param IStorage $storage * @param string $path