scope aware workflow controller and manager
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
This commit is contained in:
parent
bd5c455da4
commit
4aba1f1cff
|
@ -18,12 +18,15 @@ return array(
|
||||||
'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => $baseDir . '/../lib/Check/RequestUserAgent.php',
|
'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => $baseDir . '/../lib/Check/RequestUserAgent.php',
|
||||||
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => $baseDir . '/../lib/Check/UserGroupMembership.php',
|
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => $baseDir . '/../lib/Check/UserGroupMembership.php',
|
||||||
'OCA\\WorkflowEngine\\Command\\Index' => $baseDir . '/../lib/Command/Index.php',
|
'OCA\\WorkflowEngine\\Command\\Index' => $baseDir . '/../lib/Command/Index.php',
|
||||||
|
'OCA\\WorkflowEngine\\Controller\\AWorkflowController' => $baseDir . '/../lib/Controller/AWorkflowController.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\FlowOperations' => $baseDir . '/../lib/Controller/FlowOperations.php',
|
'OCA\\WorkflowEngine\\Controller\\FlowOperations' => $baseDir . '/../lib/Controller/FlowOperations.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => $baseDir . '/../lib/Controller/GlobalWorkflowsController.php',
|
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => $baseDir . '/../lib/Controller/GlobalWorkflowsController.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\RequestTime' => $baseDir . '/../lib/Controller/RequestTime.php',
|
'OCA\\WorkflowEngine\\Controller\\RequestTime' => $baseDir . '/../lib/Controller/RequestTime.php',
|
||||||
|
'OCA\\WorkflowEngine\\Controller\\UserWorkflowsController' => $baseDir . '/../lib/Controller/UserWorkflowsController.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\File' => $baseDir . '/../lib/Entity/File.php',
|
'OCA\\WorkflowEngine\\Entity\\File' => $baseDir . '/../lib/Entity/File.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => $baseDir . '/../lib/Entity/GenericEntityEmitterEvent.php',
|
'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => $baseDir . '/../lib/Entity/GenericEntityEmitterEvent.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => $baseDir . '/../lib/Entity/IEntityEmitterEvent.php',
|
'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => $baseDir . '/../lib/Entity/IEntityEmitterEvent.php',
|
||||||
|
'OCA\\WorkflowEngine\\Helper\\ScopeContext' => $baseDir . '/../lib/Helper/ScopeContext.php',
|
||||||
'OCA\\WorkflowEngine\\Manager' => $baseDir . '/../lib/Manager.php',
|
'OCA\\WorkflowEngine\\Manager' => $baseDir . '/../lib/Manager.php',
|
||||||
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => $baseDir . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
|
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => $baseDir . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
|
||||||
'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => $baseDir . '/../lib/Migration/Version2019Date20190808074233.php',
|
'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => $baseDir . '/../lib/Migration/Version2019Date20190808074233.php',
|
||||||
|
|
|
@ -33,12 +33,15 @@ class ComposerStaticInitWorkflowEngine
|
||||||
'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => __DIR__ . '/..' . '/../lib/Check/RequestUserAgent.php',
|
'OCA\\WorkflowEngine\\Check\\RequestUserAgent' => __DIR__ . '/..' . '/../lib/Check/RequestUserAgent.php',
|
||||||
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => __DIR__ . '/..' . '/../lib/Check/UserGroupMembership.php',
|
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => __DIR__ . '/..' . '/../lib/Check/UserGroupMembership.php',
|
||||||
'OCA\\WorkflowEngine\\Command\\Index' => __DIR__ . '/..' . '/../lib/Command/Index.php',
|
'OCA\\WorkflowEngine\\Command\\Index' => __DIR__ . '/..' . '/../lib/Command/Index.php',
|
||||||
|
'OCA\\WorkflowEngine\\Controller\\AWorkflowController' => __DIR__ . '/..' . '/../lib/Controller/AWorkflowController.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\FlowOperations' => __DIR__ . '/..' . '/../lib/Controller/FlowOperations.php',
|
'OCA\\WorkflowEngine\\Controller\\FlowOperations' => __DIR__ . '/..' . '/../lib/Controller/FlowOperations.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/GlobalWorkflowsController.php',
|
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/GlobalWorkflowsController.php',
|
||||||
'OCA\\WorkflowEngine\\Controller\\RequestTime' => __DIR__ . '/..' . '/../lib/Controller/RequestTime.php',
|
'OCA\\WorkflowEngine\\Controller\\RequestTime' => __DIR__ . '/..' . '/../lib/Controller/RequestTime.php',
|
||||||
|
'OCA\\WorkflowEngine\\Controller\\UserWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/UserWorkflowsController.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\File' => __DIR__ . '/..' . '/../lib/Entity/File.php',
|
'OCA\\WorkflowEngine\\Entity\\File' => __DIR__ . '/..' . '/../lib/Entity/File.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/GenericEntityEmitterEvent.php',
|
'OCA\\WorkflowEngine\\Entity\\GenericEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/GenericEntityEmitterEvent.php',
|
||||||
'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/IEntityEmitterEvent.php',
|
'OCA\\WorkflowEngine\\Entity\\IEntityEmitterEvent' => __DIR__ . '/..' . '/../lib/Entity/IEntityEmitterEvent.php',
|
||||||
|
'OCA\\WorkflowEngine\\Helper\\ScopeContext' => __DIR__ . '/..' . '/../lib/Helper/ScopeContext.php',
|
||||||
'OCA\\WorkflowEngine\\Manager' => __DIR__ . '/..' . '/../lib/Manager.php',
|
'OCA\\WorkflowEngine\\Manager' => __DIR__ . '/..' . '/../lib/Manager.php',
|
||||||
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => __DIR__ . '/..' . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
|
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => __DIR__ . '/..' . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
|
||||||
'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => __DIR__ . '/..' . '/../lib/Migration/Version2019Date20190808074233.php',
|
'OCA\\WorkflowEngine\\Migration\\Version2019Date20190808074233' => __DIR__ . '/..' . '/../lib/Migration/Version2019Date20190808074233.php',
|
||||||
|
|
|
@ -24,6 +24,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\WorkflowEngine\Command;
|
namespace OCA\WorkflowEngine\Command;
|
||||||
|
|
||||||
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
use OCA\WorkflowEngine\Manager;
|
use OCA\WorkflowEngine\Manager;
|
||||||
use OCP\WorkflowEngine\IManager;
|
use OCP\WorkflowEngine\IManager;
|
||||||
use Symfony\Component\Console\Command\Command;
|
use Symfony\Component\Console\Command\Command;
|
||||||
|
@ -69,8 +70,10 @@ class Index extends Command {
|
||||||
|
|
||||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||||
$ops = $this->manager->getAllOperations(
|
$ops = $this->manager->getAllOperations(
|
||||||
|
new ScopeContext(
|
||||||
$this->mappedScope($input->getArgument('scope')),
|
$this->mappedScope($input->getArgument('scope')),
|
||||||
$input->getArgument('scopeId')
|
$input->getArgument('scopeId')
|
||||||
|
)
|
||||||
);
|
);
|
||||||
$output->writeln(\json_encode($ops));
|
$output->writeln(\json_encode($ops));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,148 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2019 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @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\WorkflowEngine\Controller;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
|
use OCA\WorkflowEngine\Manager;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||||
|
use OCP\AppFramework\OCS\OCSException;
|
||||||
|
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||||
|
use OCP\AppFramework\OCSController;
|
||||||
|
use OCP\IRequest;
|
||||||
|
|
||||||
|
abstract class AWorkflowController extends OCSController {
|
||||||
|
|
||||||
|
/** @var Manager */
|
||||||
|
protected $manager;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$appName,
|
||||||
|
IRequest $request,
|
||||||
|
Manager $manager
|
||||||
|
) {
|
||||||
|
parent::__construct($appName, $request);
|
||||||
|
|
||||||
|
$this->manager = $manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
abstract protected function getScopeContext(): ScopeContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/global?format=json"
|
||||||
|
*
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function index(): DataResponse {
|
||||||
|
$operationsByClass = $this->manager->getAllOperations($this->getScopeContext());
|
||||||
|
|
||||||
|
foreach ($operationsByClass as &$operations) {
|
||||||
|
foreach ($operations as &$operation) {
|
||||||
|
$operation = $this->manager->formatOperation($operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DataResponse($operationsByClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/global/OCA\\Workflow_DocToPdf\\Operation?format=json"
|
||||||
|
*
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function show(string $id): DataResponse {
|
||||||
|
$context = $this->getScopeContext();
|
||||||
|
|
||||||
|
// The ID corresponds to a class name
|
||||||
|
$operations = $this->manager->getOperations($id, $context);
|
||||||
|
|
||||||
|
foreach ($operations as &$operation) {
|
||||||
|
$operation = $this->manager->formatOperation($operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DataResponse($operations);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws OCSBadRequestException
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
* @throws OCSException
|
||||||
|
*/
|
||||||
|
public function create(string $class, string $name, array $checks, string $operation): DataResponse {
|
||||||
|
$context = $this->getScopeContext();
|
||||||
|
try {
|
||||||
|
$operation = $this->manager->addOperation($class, $name, $checks, $operation, $context);
|
||||||
|
$operation = $this->manager->formatOperation($operation);
|
||||||
|
return new DataResponse($operation);
|
||||||
|
} catch (\UnexpectedValueException $e) {
|
||||||
|
throw new OCSBadRequestException($e->getMessage(), $e);
|
||||||
|
} catch (\DomainException $e) {
|
||||||
|
throw new OCSForbiddenException($e->getMessage(), $e);
|
||||||
|
} catch(DBALException $e) {
|
||||||
|
throw new OCSException('An internal error occurred', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws OCSBadRequestException
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
* @throws OCSException
|
||||||
|
*/
|
||||||
|
public function update(int $id, string $name, array $checks, string $operation): DataResponse {
|
||||||
|
try {
|
||||||
|
$operation = $this->manager->updateOperation($id, $name, $checks, $operation, $this->getScopeContext());
|
||||||
|
$operation = $this->manager->formatOperation($operation);
|
||||||
|
return new DataResponse($operation);
|
||||||
|
} catch (\UnexpectedValueException $e) {
|
||||||
|
throw new OCSBadRequestException($e->getMessage(), $e);
|
||||||
|
} catch (\DomainException $e) {
|
||||||
|
throw new OCSForbiddenException($e->getMessage(), $e);
|
||||||
|
} catch(DBALException $e) {
|
||||||
|
throw new OCSException('An internal error occurred', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws OCSBadRequestException
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
* @throws OCSException
|
||||||
|
*/
|
||||||
|
public function destroy(int $id): DataResponse {
|
||||||
|
try {
|
||||||
|
$deleted = $this->manager->deleteOperation($id, $this->getScopeContext());
|
||||||
|
return new DataResponse($deleted);
|
||||||
|
} catch (\UnexpectedValueException $e) {
|
||||||
|
throw new OCSBadRequestException($e->getMessage(), $e);
|
||||||
|
} catch (\DomainException $e) {
|
||||||
|
throw new OCSForbiddenException($e->getMessage(), $e);
|
||||||
|
} catch(DBALException $e) {
|
||||||
|
throw new OCSException('An internal error occurred', $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,88 +24,18 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\WorkflowEngine\Controller;
|
namespace OCA\WorkflowEngine\Controller;
|
||||||
|
|
||||||
use OCA\WorkflowEngine\Manager;
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
use OCP\AppFramework\Http\DataResponse;
|
use OCP\WorkflowEngine\IManager;
|
||||||
use OCP\AppFramework\OCS\OCSBadRequestException;
|
|
||||||
use OCP\AppFramework\OCSController;
|
|
||||||
use OCP\IRequest;
|
|
||||||
|
|
||||||
class GlobalWorkflowsController extends OCSController {
|
class GlobalWorkflowsController extends AWorkflowController {
|
||||||
|
|
||||||
/** @var Manager */
|
/** @var ScopeContext */
|
||||||
private $manager;
|
private $scopeContext;
|
||||||
|
|
||||||
public function __construct(
|
protected function getScopeContext(): ScopeContext {
|
||||||
$appName,
|
if($this->scopeContext === null) {
|
||||||
IRequest $request,
|
$this->scopeContext = new ScopeContext(IManager::SCOPE_ADMIN);
|
||||||
Manager $manager
|
|
||||||
) {
|
|
||||||
parent::__construct($appName, $request);
|
|
||||||
|
|
||||||
$this->manager = $manager;
|
|
||||||
}
|
}
|
||||||
|
return $this->scopeContext;
|
||||||
/**
|
|
||||||
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/global?format=json"
|
|
||||||
*/
|
|
||||||
public function index(): DataResponse {
|
|
||||||
$operationsByClass = $this->manager->getAllOperations();
|
|
||||||
|
|
||||||
foreach ($operationsByClass as &$operations) {
|
|
||||||
foreach ($operations as &$operation) {
|
|
||||||
$operation = $this->manager->formatOperation($operation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DataResponse($operationsByClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws OCSBadRequestException
|
|
||||||
*
|
|
||||||
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/global/OCA\\Workflow_DocToPdf\\Operation?format=json"
|
|
||||||
*/
|
|
||||||
public function show(string $id): DataResponse {
|
|
||||||
// The ID corresponds to a class name
|
|
||||||
$operations = $this->manager->getOperations($id);
|
|
||||||
|
|
||||||
foreach ($operations as &$operation) {
|
|
||||||
$operation = $this->manager->formatOperation($operation);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DataResponse($operations);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws OCSBadRequestException
|
|
||||||
*/
|
|
||||||
public function create(string $class, string $name, array $checks, string $operation): DataResponse {
|
|
||||||
try {
|
|
||||||
$operation = $this->manager->addOperation($class, $name, $checks, $operation);
|
|
||||||
$operation = $this->manager->formatOperation($operation);
|
|
||||||
return new DataResponse($operation);
|
|
||||||
} catch (\UnexpectedValueException $e) {
|
|
||||||
throw new OCSBadRequestException($e->getMessage(), $e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws OCSBadRequestException
|
|
||||||
*/
|
|
||||||
public function update(int $id, string $name, array $checks, string $operation): DataResponse {
|
|
||||||
try {
|
|
||||||
$operation = $this->manager->updateOperation($id, $name, $checks, $operation);
|
|
||||||
$operation = $this->manager->formatOperation($operation);
|
|
||||||
return new DataResponse($operation);
|
|
||||||
} catch (\UnexpectedValueException $e) {
|
|
||||||
throw new OCSBadRequestException($e->getMessage(), $e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*/
|
|
||||||
public function destroy(int $id): DataResponse {
|
|
||||||
$deleted = $this->manager->deleteOperation((int) $id);
|
|
||||||
return new DataResponse($deleted);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2019 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @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\WorkflowEngine\Controller;
|
||||||
|
|
||||||
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
|
use OCA\WorkflowEngine\Manager;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCP\AppFramework\OCS\OCSBadRequestException;
|
||||||
|
use OCP\AppFramework\OCS\OCSForbiddenException;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
use OCP\WorkflowEngine\IManager;
|
||||||
|
|
||||||
|
class UserWorkflowsController extends AWorkflowController {
|
||||||
|
|
||||||
|
/** @var IUserSession */
|
||||||
|
private $session;
|
||||||
|
|
||||||
|
/** @var ScopeContext */
|
||||||
|
private $scopeContext;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
$appName,
|
||||||
|
IRequest $request,
|
||||||
|
Manager $manager,
|
||||||
|
IUserSession $session
|
||||||
|
) {
|
||||||
|
parent::__construct($appName, $request, $manager);
|
||||||
|
|
||||||
|
$this->session = $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all configured workflow rules
|
||||||
|
*
|
||||||
|
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/user?format=json"
|
||||||
|
*
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function index(): DataResponse {
|
||||||
|
return parent::index();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* Example: curl -u joann -H "OCS-APIREQUEST: true" "http://my.nc.srvr/ocs/v2.php/apps/workflowengine/api/v1/workflows/user/OCA\\Workflow_DocToPdf\\Operation?format=json"
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function show(string $id): DataResponse {
|
||||||
|
return parent::show($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @throws OCSBadRequestException
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function create(string $class, string $name, array $checks, string $operation): DataResponse {
|
||||||
|
return parent::create($class, $name, $checks, $operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @throws OCSBadRequestException
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function update(int $id, string $name, array $checks, string $operation): DataResponse {
|
||||||
|
return parent::update($id, $name, $checks, $operation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
public function destroy(int $id): DataResponse {
|
||||||
|
return parent::destroy($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws OCSForbiddenException
|
||||||
|
*/
|
||||||
|
protected function getScopeContext(): ScopeContext {
|
||||||
|
if($this->scopeContext === null) {
|
||||||
|
$user = $this->session->getUser();
|
||||||
|
if(!$user) {
|
||||||
|
throw new OCSForbiddenException('User not logged in');
|
||||||
|
}
|
||||||
|
$this->scopeContext = new ScopeContext(IManager::SCOPE_USER, $user->getUID());
|
||||||
|
}
|
||||||
|
return $this->scopeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2019 Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||||
|
*
|
||||||
|
* @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\WorkflowEngine\Helper;
|
||||||
|
|
||||||
|
use OCP\WorkflowEngine\IManager;
|
||||||
|
|
||||||
|
class ScopeContext {
|
||||||
|
/** @var int */
|
||||||
|
private $scope;
|
||||||
|
/** @var string */
|
||||||
|
private $scopeId;
|
||||||
|
/** @var string */
|
||||||
|
private $hash;
|
||||||
|
|
||||||
|
public function __construct(int $scope, string $scopeId = null) {
|
||||||
|
$this->scope = $this->evaluateScope($scope);
|
||||||
|
$this->scopeId = $this->evaluateScopeId($scopeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function evaluateScope(int $scope): int {
|
||||||
|
if(in_array($scope, [IManager::SCOPE_ADMIN, IManager::SCOPE_USER], true)) {
|
||||||
|
return $scope;
|
||||||
|
}
|
||||||
|
throw new \InvalidArgumentException('Invalid scope');
|
||||||
|
}
|
||||||
|
|
||||||
|
private function evaluateScopeId(string $scopeId = null): string {
|
||||||
|
if($this->scope === IManager::SCOPE_USER
|
||||||
|
&& trim((string)$scopeId) === '')
|
||||||
|
{
|
||||||
|
throw new \InvalidArgumentException('user scope requires a user id');
|
||||||
|
}
|
||||||
|
return trim((string)$scopeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getScope(): int {
|
||||||
|
return $this->scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getScopeId(): string {
|
||||||
|
return $this->scopeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHash(): string {
|
||||||
|
if($this->hash === null) {
|
||||||
|
$this->hash = \hash('sha256', $this->getScope() . '::' . $this->getScopeId());
|
||||||
|
}
|
||||||
|
return $this->hash;
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,7 +23,10 @@ namespace OCA\WorkflowEngine;
|
||||||
|
|
||||||
|
|
||||||
use OC\Files\Storage\Wrapper\Jail;
|
use OC\Files\Storage\Wrapper\Jail;
|
||||||
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use OC\Cache\CappedMemoryCache;
|
||||||
use OCA\WorkflowEngine\Entity\File;
|
use OCA\WorkflowEngine\Entity\File;
|
||||||
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
use OCP\AppFramework\QueryException;
|
use OCP\AppFramework\QueryException;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
use OCP\Files\Storage\IStorage;
|
use OCP\Files\Storage\IStorage;
|
||||||
|
@ -74,6 +77,10 @@ class Manager implements IManager, IEntityAware {
|
||||||
|
|
||||||
/** @var ILogger */
|
/** @var ILogger */
|
||||||
protected $logger;
|
protected $logger;
|
||||||
|
|
||||||
|
/** @var CappedMemoryCache */
|
||||||
|
protected $operationsByScope = [];
|
||||||
|
|
||||||
/** @var IUserSession */
|
/** @var IUserSession */
|
||||||
protected $session;
|
protected $session;
|
||||||
|
|
||||||
|
@ -95,6 +102,7 @@ class Manager implements IManager, IEntityAware {
|
||||||
$this->l = $l;
|
$this->l = $l;
|
||||||
$this->eventDispatcher = $eventDispatcher;
|
$this->eventDispatcher = $eventDispatcher;
|
||||||
$this->logger = $logger;
|
$this->logger = $logger;
|
||||||
|
$this->operationsByScope = new CappedMemoryCache(64);
|
||||||
$this->session = $session;
|
$this->session = $session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +122,16 @@ class Manager implements IManager, IEntityAware {
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
public function getMatchingOperations($class, $returnFirstMatchingOperationOnly = true) {
|
public function getMatchingOperations($class, $returnFirstMatchingOperationOnly = true) {
|
||||||
$operations = $this->getOperations($class);
|
$scopes[] = new ScopeContext(IManager::SCOPE_ADMIN);
|
||||||
|
$user = $this->session->getUser();
|
||||||
|
if($user !== null) {
|
||||||
|
$scopes[] = new ScopeContext(IManager::SCOPE_USER, $user->getUID());
|
||||||
|
}
|
||||||
|
|
||||||
|
$operations = [];
|
||||||
|
foreach ($scopes as $scope) {
|
||||||
|
$operations = array_merge($operations, $this->getOperations($class, $scope));
|
||||||
|
}
|
||||||
|
|
||||||
$matches = [];
|
$matches = [];
|
||||||
foreach ($operations as $operation) {
|
foreach ($operations as $operation) {
|
||||||
|
@ -160,19 +177,10 @@ class Manager implements IManager, IEntityAware {
|
||||||
throw new \UnexpectedValueException($this->l->t('Check %s is invalid or does not exist', $check['class']));
|
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 {
|
public function getAllOperations(ScopeContext $scopeContext): array {
|
||||||
if(!in_array($scope, [IManager::SCOPE_ADMIN, IManager::SCOPE_USER])) {
|
if(isset($this->operations[$scopeContext->getHash()])) {
|
||||||
throw new \InvalidArgumentException('Provided value for scope is not supported');
|
return $this->operations[$scopeContext->getHash()];
|
||||||
}
|
}
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->operations = [];
|
|
||||||
|
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
|
@ -181,48 +189,29 @@ class Manager implements IManager, IEntityAware {
|
||||||
->leftJoin('o', 'flow_operations_scope', 's', $query->expr()->eq('o.id', 's.operation_id'))
|
->leftJoin('o', 'flow_operations_scope', 's', $query->expr()->eq('o.id', 's.operation_id'))
|
||||||
->where($query->expr()->eq('s.type', $query->createParameter('scope')));
|
->where($query->expr()->eq('s.type', $query->createParameter('scope')));
|
||||||
|
|
||||||
if($scope === IManager::SCOPE_USER) {
|
if($scopeContext->getScope() === IManager::SCOPE_USER) {
|
||||||
$query->andWhere($query->expr()->eq('s.value', $query->createParameter('scopeId')));
|
$query->andWhere($query->expr()->eq('s.value', $query->createParameter('scopeId')));
|
||||||
}
|
}
|
||||||
|
|
||||||
$query->setParameters(['scope' => $scope, 'scopeId' => $scopeId]);
|
$query->setParameters(['scope' => $scopeContext->getScope(), 'scopeId' => $scopeContext->getScopeId()]);
|
||||||
|
|
||||||
$result = $query->execute();
|
$result = $query->execute();
|
||||||
|
|
||||||
|
$this->operations[$scopeContext->getHash()] = [];
|
||||||
while ($row = $result->fetch()) {
|
while ($row = $result->fetch()) {
|
||||||
if(!isset($this->operations[$row['class']])) {
|
if(!isset($this->operations[$scopeContext->getHash()][$row['class']])) {
|
||||||
$this->operations[$row['class']] = [];
|
$this->operations[$scopeContext->getHash()][$row['class']] = [];
|
||||||
}
|
}
|
||||||
$this->operations[$row['class']][] = $row;
|
$this->operations[$scopeContext->getHash()][$row['class']][] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->operations;
|
return $this->operations[$scopeContext->getHash()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getOperations(string $class, ScopeContext $scopeContext): array {
|
||||||
/**
|
if (!isset($this->operations[$scopeContext->getHash()])) {
|
||||||
* @param string $class
|
$this->getAllOperations($scopeContext);
|
||||||
* @return array[]
|
|
||||||
*/
|
|
||||||
public function getOperations($class) {
|
|
||||||
if (isset($this->operations[$class])) {
|
|
||||||
return $this->operations[$class];
|
|
||||||
}
|
}
|
||||||
|
return $this->operations[$scopeContext->getHash()][$class] ?? [];
|
||||||
$query = $this->connection->getQueryBuilder();
|
|
||||||
|
|
||||||
$query->select('*')
|
|
||||||
->from('flow_operations')
|
|
||||||
->where($query->expr()->eq('class', $query->createNamedParameter($class)));
|
|
||||||
$result = $query->execute();
|
|
||||||
|
|
||||||
$this->operations[$class] = [];
|
|
||||||
while ($row = $result->fetch()) {
|
|
||||||
$this->operations[$class][] = $row;
|
|
||||||
}
|
|
||||||
$result->closeCursor();
|
|
||||||
|
|
||||||
return $this->operations[$class];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -246,22 +235,7 @@ class Manager implements IManager, IEntityAware {
|
||||||
throw new \UnexpectedValueException($this->l->t('Operation #%s does not exist', [$id]));
|
throw new \UnexpectedValueException($this->l->t('Operation #%s does not exist', [$id]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
protected function insertOperation(string $class, string $name, array $checkIds, string $operation): int {
|
||||||
* @param string $class
|
|
||||||
* @param string $name
|
|
||||||
* @param array[] $checks
|
|
||||||
* @param string $operation
|
|
||||||
* @return array The added operation
|
|
||||||
* @throws \UnexpectedValueException
|
|
||||||
*/
|
|
||||||
public function addOperation($class, $name, array $checks, $operation) {
|
|
||||||
$this->validateOperation($class, $name, $checks, $operation);
|
|
||||||
|
|
||||||
$checkIds = [];
|
|
||||||
foreach ($checks as $check) {
|
|
||||||
$checkIds[] = $this->addCheck($check['class'], $check['operator'], $check['value']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
$query->insert('flow_operations')
|
$query->insert('flow_operations')
|
||||||
->values([
|
->values([
|
||||||
|
@ -272,10 +246,68 @@ class Manager implements IManager, IEntityAware {
|
||||||
]);
|
]);
|
||||||
$query->execute();
|
$query->execute();
|
||||||
|
|
||||||
$id = $query->getLastInsertId();
|
return $query->getLastInsertId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @param string $name
|
||||||
|
* @param array[] $checks
|
||||||
|
* @param string $operation
|
||||||
|
* @return array The added operation
|
||||||
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws DBALException
|
||||||
|
*/
|
||||||
|
public function addOperation($class, $name, array $checks, $operation, ScopeContext $scope) {
|
||||||
|
$this->validateOperation($class, $name, $checks, $operation);
|
||||||
|
|
||||||
|
$this->connection->beginTransaction();
|
||||||
|
|
||||||
|
try {
|
||||||
|
$checkIds = [];
|
||||||
|
foreach ($checks as $check) {
|
||||||
|
$checkIds[] = $this->addCheck($check['class'], $check['operator'], $check['value']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $this->insertOperation($class, $name, $checkIds, $operation);
|
||||||
|
$this->addScope($id, $scope);
|
||||||
|
|
||||||
|
$this->connection->commit();
|
||||||
|
} catch (DBALException $e) {
|
||||||
|
$this->connection->rollBack();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
return $this->getOperation($id);
|
return $this->getOperation($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function canModify(int $id, ScopeContext $scopeContext):bool {
|
||||||
|
if(isset($this->operationsByScope[$scopeContext->getHash()])) {
|
||||||
|
return in_array($id, $this->operationsByScope[$scopeContext->getHash()], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb = $this->connection->getQueryBuilder();
|
||||||
|
$qb = $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()->eq('s.type', $qb->createParameter('scope')));
|
||||||
|
|
||||||
|
if($scopeContext->getScope() !== IManager::SCOPE_ADMIN) {
|
||||||
|
$qb->where($qb->expr()->eq('s.value', $qb->createParameter('scopeId')));
|
||||||
|
}
|
||||||
|
|
||||||
|
$qb->setParameters(['scope' => $scopeContext->getScope(), 'scopeId' => $scopeContext->getScopeId()]);
|
||||||
|
$result = $qb->execute();
|
||||||
|
|
||||||
|
$this->operationsByScope[$scopeContext->getHash()] = [];
|
||||||
|
while($opId = $result->fetchColumn(0)) {
|
||||||
|
$this->operationsByScope[$scopeContext->getHash()][] = (int)$opId;
|
||||||
|
}
|
||||||
|
$result->closeCursor();
|
||||||
|
|
||||||
|
return in_array($id, $this->operationsByScope[$scopeContext->getHash()], true);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @param string $name
|
* @param string $name
|
||||||
|
@ -283,12 +315,19 @@ class Manager implements IManager, IEntityAware {
|
||||||
* @param string $operation
|
* @param string $operation
|
||||||
* @return array The updated operation
|
* @return array The updated operation
|
||||||
* @throws \UnexpectedValueException
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws \DomainException
|
||||||
|
* @throws DBALException
|
||||||
*/
|
*/
|
||||||
public function updateOperation($id, $name, array $checks, $operation) {
|
public function updateOperation($id, $name, array $checks, $operation, ScopeContext $scopeContext): array {
|
||||||
|
if(!$this->canModify($id, $scopeContext)) {
|
||||||
|
throw new \DomainException('Target operation not within scope');
|
||||||
|
};
|
||||||
$row = $this->getOperation($id);
|
$row = $this->getOperation($id);
|
||||||
$this->validateOperation($row['class'], $name, $checks, $operation);
|
$this->validateOperation($row['class'], $name, $checks, $operation);
|
||||||
|
|
||||||
$checkIds = [];
|
$checkIds = [];
|
||||||
|
try {
|
||||||
|
$this->connection->beginTransaction();
|
||||||
foreach ($checks as $check) {
|
foreach ($checks as $check) {
|
||||||
$checkIds[] = $this->addCheck($check['class'], $check['operator'], $check['value']);
|
$checkIds[] = $this->addCheck($check['class'], $check['operator'], $check['value']);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +339,12 @@ class Manager implements IManager, IEntityAware {
|
||||||
->set('operation', $query->createNamedParameter($operation))
|
->set('operation', $query->createNamedParameter($operation))
|
||||||
->where($query->expr()->eq('id', $query->createNamedParameter($id)));
|
->where($query->expr()->eq('id', $query->createNamedParameter($id)));
|
||||||
$query->execute();
|
$query->execute();
|
||||||
|
$this->connection->commit();
|
||||||
|
} catch (DBALException $e) {
|
||||||
|
$this->connection->rollBack();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
unset($this->operations[$scopeContext->getHash()]);
|
||||||
|
|
||||||
return $this->getOperation($id);
|
return $this->getOperation($id);
|
||||||
}
|
}
|
||||||
|
@ -308,12 +353,36 @@ class Manager implements IManager, IEntityAware {
|
||||||
* @param int $id
|
* @param int $id
|
||||||
* @return bool
|
* @return bool
|
||||||
* @throws \UnexpectedValueException
|
* @throws \UnexpectedValueException
|
||||||
|
* @throws DBALException
|
||||||
|
* @throws \DomainException
|
||||||
*/
|
*/
|
||||||
public function deleteOperation($id) {
|
public function deleteOperation($id, ScopeContext $scopeContext) {
|
||||||
|
if(!$this->canModify($id, $scopeContext)) {
|
||||||
|
throw new \DomainException('Target operation not within scope');
|
||||||
|
};
|
||||||
$query = $this->connection->getQueryBuilder();
|
$query = $this->connection->getQueryBuilder();
|
||||||
$query->delete('flow_operations')
|
try {
|
||||||
->where($query->expr()->eq('id', $query->createNamedParameter($id)));
|
$this->connection->beginTransaction();
|
||||||
return (bool) $query->execute();
|
$result = (bool)$query->delete('flow_operations')
|
||||||
|
->where($query->expr()->eq('id', $query->createNamedParameter($id)))
|
||||||
|
->execute();
|
||||||
|
if($result) {
|
||||||
|
$qb = $this->connection->getQueryBuilder();
|
||||||
|
$result &= (bool)$qb->delete('flow_operations_scope')
|
||||||
|
->where($qb->expr()->eq('operation_id', $query->createNamedParameter($id)))
|
||||||
|
->execute();
|
||||||
|
}
|
||||||
|
$this->connection->commit();
|
||||||
|
} catch (DBALException $e) {
|
||||||
|
$this->connection->rollBack();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isset($this->operations[$scopeContext->getHash()])) {
|
||||||
|
unset($this->operations[$scopeContext->getHash()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -427,6 +496,18 @@ class Manager implements IManager, IEntityAware {
|
||||||
return $query->getLastInsertId();
|
return $query->getLastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function addScope(int $operationId, ScopeContext $scope): void {
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
|
||||||
|
$insertQuery = $query->insert('flow_operations_scope');
|
||||||
|
$insertQuery->values([
|
||||||
|
'operation_id' => $query->createNamedParameter($operationId),
|
||||||
|
'type' => $query->createNamedParameter($scope->getScope()),
|
||||||
|
'value' => $query->createNamedParameter($scope->getScopeId()),
|
||||||
|
]);
|
||||||
|
$insertQuery->execute();
|
||||||
|
}
|
||||||
|
|
||||||
public function formatOperation(array $operation): array {
|
public function formatOperation(array $operation): array {
|
||||||
$checkIds = json_decode($operation['checks'], true);
|
$checkIds = json_decode($operation['checks'], true);
|
||||||
$checks = $this->getChecks($checkIds);
|
$checks = $this->getChecks($checkIds);
|
||||||
|
|
|
@ -23,12 +23,16 @@ namespace OCA\WorkflowEngine\Tests;
|
||||||
|
|
||||||
|
|
||||||
use OCA\WorkflowEngine\Entity\File;
|
use OCA\WorkflowEngine\Entity\File;
|
||||||
|
use OCA\WorkflowEngine\Helper\ScopeContext;
|
||||||
use OCA\WorkflowEngine\Manager;
|
use OCA\WorkflowEngine\Manager;
|
||||||
use OCP\IDBConnection;
|
use OCP\IDBConnection;
|
||||||
use OCP\IL10N;
|
use OCP\IL10N;
|
||||||
use OCP\ILogger;
|
use OCP\ILogger;
|
||||||
use OCP\IServerContainer;
|
use OCP\IServerContainer;
|
||||||
|
use OCP\WorkflowEngine\ICheck;
|
||||||
use OCP\WorkflowEngine\IEntity;
|
use OCP\WorkflowEngine\IEntity;
|
||||||
|
use OCP\WorkflowEngine\IManager;
|
||||||
|
use OCP\WorkflowEngine\IOperation;
|
||||||
use PHPUnit\Framework\MockObject\MockObject;
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
|
@ -74,19 +78,39 @@ class ManagerTest extends TestCase {
|
||||||
$this->eventDispatcher,
|
$this->eventDispatcher,
|
||||||
$this->logger
|
$this->logger
|
||||||
);
|
);
|
||||||
$this->clearChecks();
|
$this->clearTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function tearDown() {
|
protected function tearDown() {
|
||||||
$this->clearChecks();
|
$this->clearTables();
|
||||||
parent::tearDown();
|
parent::tearDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function clearChecks() {
|
/**
|
||||||
|
* @return MockObject|ScopeContext
|
||||||
|
*/
|
||||||
|
protected function buildScope(string $scopeId = null): MockObject {
|
||||||
|
$scopeContext = $this->createMock(ScopeContext::class);
|
||||||
|
$scopeContext->expects($this->any())
|
||||||
|
->method('getScope')
|
||||||
|
->willReturn($scopeId ? IManager::SCOPE_USER : IManager::SCOPE_ADMIN);
|
||||||
|
$scopeContext->expects($this->any())
|
||||||
|
->method('getScopeId')
|
||||||
|
->willReturn($scopeId ?? '');
|
||||||
|
$scopeContext->expects($this->any())
|
||||||
|
->method('getHash')
|
||||||
|
->willReturn(md5($scopeId ?? ''));
|
||||||
|
|
||||||
|
return $scopeContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearTables() {
|
||||||
$query = $this->db->getQueryBuilder();
|
$query = $this->db->getQueryBuilder();
|
||||||
$query->delete('flow_checks')
|
foreach(['flow_checks', 'flow_operations', 'flow_operations_scope'] as $table) {
|
||||||
|
$query->delete($table)
|
||||||
->execute();
|
->execute();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testChecks() {
|
public function testChecks() {
|
||||||
$check1 = $this->invokePrivate($this->manager, 'addCheck', ['Test', 'equal', 1]);
|
$check1 = $this->invokePrivate($this->manager, 'addCheck', ['Test', 'equal', 1]);
|
||||||
|
@ -109,6 +133,221 @@ class ManagerTest extends TestCase {
|
||||||
$this->assertArrayHasKey($check2, $data);
|
$this->assertArrayHasKey($check2, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testScope() {
|
||||||
|
$adminScope = $this->buildScope();
|
||||||
|
$userScope = $this->buildScope('jackie');
|
||||||
|
|
||||||
|
$opId1 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test01', [11, 22], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
|
||||||
|
|
||||||
|
$opId2 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test02', [33, 22], 'bar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
|
||||||
|
$opId3 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test03', [11, 44], 'foobar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
|
||||||
|
|
||||||
|
$this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId1, $adminScope]));
|
||||||
|
$this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId2, $adminScope]));
|
||||||
|
$this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId3, $adminScope]));
|
||||||
|
|
||||||
|
$this->assertFalse($this->invokePrivate($this->manager, 'canModify', [$opId1, $userScope]));
|
||||||
|
$this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId2, $userScope]));
|
||||||
|
$this->assertTrue($this->invokePrivate($this->manager, 'canModify', [$opId3, $userScope]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetAllOperations() {
|
||||||
|
$adminScope = $this->buildScope();
|
||||||
|
$userScope = $this->buildScope('jackie');
|
||||||
|
|
||||||
|
$opId1 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
|
||||||
|
|
||||||
|
$opId2 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
|
||||||
|
$opId3 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestUserOp', 'Test03', [11, 44], 'foobar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
|
||||||
|
|
||||||
|
$adminOps = $this->manager->getAllOperations($adminScope);
|
||||||
|
$userOps = $this->manager->getAllOperations($userScope);
|
||||||
|
|
||||||
|
$this->assertSame(1, count($adminOps));
|
||||||
|
$this->assertTrue(array_key_exists('OCA\WFE\TestAdminOp', $adminOps));
|
||||||
|
$this->assertFalse(array_key_exists('OCA\WFE\TestUserOp', $adminOps));
|
||||||
|
|
||||||
|
$this->assertSame(1, count($userOps));
|
||||||
|
$this->assertFalse(array_key_exists('OCA\WFE\TestAdminOp', $userOps));
|
||||||
|
$this->assertTrue(array_key_exists('OCA\WFE\TestUserOp', $userOps));
|
||||||
|
$this->assertSame(2, count($userOps['OCA\WFE\TestUserOp']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetOperations() {
|
||||||
|
$adminScope = $this->buildScope();
|
||||||
|
$userScope = $this->buildScope('jackie');
|
||||||
|
|
||||||
|
$opId1 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test01', [11, 22], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
|
||||||
|
$opId4 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\OtherTestOp', 'Test04', [5], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId4, $adminScope]);
|
||||||
|
|
||||||
|
$opId2 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test02', [33, 22], 'bar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
|
||||||
|
$opId3 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestOp', 'Test03', [11, 44], 'foobar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId3, $userScope]);
|
||||||
|
$opId5 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\OtherTestOp', 'Test05', [5], 'foobar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId5, $userScope]);
|
||||||
|
|
||||||
|
$adminOps = $this->manager->getOperations('OCA\WFE\TestOp', $adminScope);
|
||||||
|
$userOps = $this->manager->getOperations('OCA\WFE\TestOp', $userScope);
|
||||||
|
|
||||||
|
$this->assertSame(1, count($adminOps));
|
||||||
|
array_walk($adminOps, function ($op) {
|
||||||
|
$this->assertTrue($op['class'] === 'OCA\WFE\TestOp');
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->assertSame(2, count($userOps));
|
||||||
|
array_walk($userOps, function ($op) {
|
||||||
|
$this->assertTrue($op['class'] === 'OCA\WFE\TestOp');
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUpdateOperation() {
|
||||||
|
$adminScope = $this->buildScope();
|
||||||
|
$userScope = $this->buildScope('jackie');
|
||||||
|
|
||||||
|
$this->container->expects($this->any())
|
||||||
|
->method('query')
|
||||||
|
->willReturnCallback(function ($class) {
|
||||||
|
if(substr($class, -2) === 'Op') {
|
||||||
|
return $this->createMock(IOperation::class);
|
||||||
|
}
|
||||||
|
return $this->createMock(ICheck::class);
|
||||||
|
});
|
||||||
|
|
||||||
|
$opId1 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
|
||||||
|
|
||||||
|
$opId2 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
|
||||||
|
|
||||||
|
$check1 = ['class' => 'OCA\WFE\C22', 'operator' => 'eq', 'value' => 'asdf'];
|
||||||
|
$check2 = ['class' => 'OCA\WFE\C33', 'operator' => 'eq', 'value' => 23456];
|
||||||
|
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$op = $this->manager->updateOperation($opId1, 'Test01a', [$check1, $check2], 'foohur', $adminScope);
|
||||||
|
$this->assertSame('Test01a', $op['name']);
|
||||||
|
$this->assertSame('foohur', $op['operation']);
|
||||||
|
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$op = $this->manager->updateOperation($opId2, 'Test02a', [$check1], 'barfoo', $userScope);
|
||||||
|
$this->assertSame('Test02a', $op['name']);
|
||||||
|
$this->assertSame('barfoo', $op['operation']);
|
||||||
|
|
||||||
|
foreach([[$adminScope, $opId2], [$userScope, $opId1]] as $run) {
|
||||||
|
try {
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$this->manager->updateOperation($run[1], 'Evil', [$check2], 'hackx0r', $run[0]);
|
||||||
|
$this->assertTrue(false, 'DomainException not thrown');
|
||||||
|
} catch (\DomainException $e) {
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testDeleteOperation() {
|
||||||
|
$adminScope = $this->buildScope();
|
||||||
|
$userScope = $this->buildScope('jackie');
|
||||||
|
|
||||||
|
$opId1 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestAdminOp', 'Test01', [11, 22], 'foo']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId1, $adminScope]);
|
||||||
|
|
||||||
|
$opId2 = $this->invokePrivate(
|
||||||
|
$this->manager,
|
||||||
|
'insertOperation',
|
||||||
|
['OCA\WFE\TestUserOp', 'Test02', [33, 22], 'bar']
|
||||||
|
);
|
||||||
|
$this->invokePrivate($this->manager, 'addScope', [$opId2, $userScope]);
|
||||||
|
|
||||||
|
foreach([[$adminScope, $opId2], [$userScope, $opId1]] as $run) {
|
||||||
|
try {
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$this->manager->deleteOperation($run[1], $run[0]);
|
||||||
|
$this->assertTrue(false, 'DomainException not thrown');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->assertInstanceOf(\DomainException::class, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$this->manager->deleteOperation($opId1, $adminScope);
|
||||||
|
/** @noinspection PhpUnhandledExceptionInspection */
|
||||||
|
$this->manager->deleteOperation($opId2, $userScope);
|
||||||
|
|
||||||
|
foreach([$opId1, $opId2] as $opId) {
|
||||||
|
try {
|
||||||
|
$this->invokePrivate($this->manager, 'getOperation', [$opId]);
|
||||||
|
$this->assertTrue(false, 'UnexpectedValueException not thrown');
|
||||||
|
} catch(\Exception $e) {
|
||||||
|
$this->assertInstanceOf(\UnexpectedValueException::class, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function testGetEntitiesListBuildInOnly() {
|
public function testGetEntitiesListBuildInOnly() {
|
||||||
$fileEntityMock = $this->createMock(File::class);
|
$fileEntityMock = $this->createMock(File::class);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue