feat(workflowengine): Add openapi for workflow engine

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2026-02-12 09:57:54 +01:00
parent 3d4774edb6
commit 4134df9eda
No known key found for this signature in database
GPG key ID: F72FA5B49FFA96B0
18 changed files with 5356 additions and 65 deletions

View file

@ -1,17 +0,0 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
return [
'routes' => [
['name' => 'requestTime#getTimezones', 'url' => '/timezones', 'verb' => 'GET'],
],
'ocs-resources' => [
'global_workflows' => ['url' => '/api/v1/workflows/global'],
'user_workflows' => ['url' => '/api/v1/workflows/user'],
],
];

View file

@ -21,7 +21,7 @@ return array(
'OCA\\WorkflowEngine\\Check\\TFileCheck' => $baseDir . '/../lib/Check/TFileCheck.php',
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => $baseDir . '/../lib/Check/UserGroupMembership.php',
'OCA\\WorkflowEngine\\Command\\Index' => $baseDir . '/../lib/Command/Index.php',
'OCA\\WorkflowEngine\\Controller\\AWorkflowController' => $baseDir . '/../lib/Controller/AWorkflowController.php',
'OCA\\WorkflowEngine\\Controller\\AWorkflowOCSController' => $baseDir . '/../lib/Controller/AWorkflowOCSController.php',
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => $baseDir . '/../lib/Controller/GlobalWorkflowsController.php',
'OCA\\WorkflowEngine\\Controller\\RequestTimeController' => $baseDir . '/../lib/Controller/RequestTimeController.php',
'OCA\\WorkflowEngine\\Controller\\UserWorkflowsController' => $baseDir . '/../lib/Controller/UserWorkflowsController.php',
@ -33,6 +33,7 @@ return array(
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => $baseDir . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
'OCA\\WorkflowEngine\\Migration\\Version2000Date20190808074233' => $baseDir . '/../lib/Migration/Version2000Date20190808074233.php',
'OCA\\WorkflowEngine\\Migration\\Version2200Date20210805101925' => $baseDir . '/../lib/Migration/Version2200Date20210805101925.php',
'OCA\\WorkflowEngine\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
'OCA\\WorkflowEngine\\Service\\Logger' => $baseDir . '/../lib/Service/Logger.php',
'OCA\\WorkflowEngine\\Service\\RuleMatcher' => $baseDir . '/../lib/Service/RuleMatcher.php',
'OCA\\WorkflowEngine\\Settings\\ASettings' => $baseDir . '/../lib/Settings/ASettings.php',

View file

@ -36,7 +36,7 @@ class ComposerStaticInitWorkflowEngine
'OCA\\WorkflowEngine\\Check\\TFileCheck' => __DIR__ . '/..' . '/../lib/Check/TFileCheck.php',
'OCA\\WorkflowEngine\\Check\\UserGroupMembership' => __DIR__ . '/..' . '/../lib/Check/UserGroupMembership.php',
'OCA\\WorkflowEngine\\Command\\Index' => __DIR__ . '/..' . '/../lib/Command/Index.php',
'OCA\\WorkflowEngine\\Controller\\AWorkflowController' => __DIR__ . '/..' . '/../lib/Controller/AWorkflowController.php',
'OCA\\WorkflowEngine\\Controller\\AWorkflowOCSController' => __DIR__ . '/..' . '/../lib/Controller/AWorkflowOCSController.php',
'OCA\\WorkflowEngine\\Controller\\GlobalWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/GlobalWorkflowsController.php',
'OCA\\WorkflowEngine\\Controller\\RequestTimeController' => __DIR__ . '/..' . '/../lib/Controller/RequestTimeController.php',
'OCA\\WorkflowEngine\\Controller\\UserWorkflowsController' => __DIR__ . '/..' . '/../lib/Controller/UserWorkflowsController.php',
@ -48,6 +48,7 @@ class ComposerStaticInitWorkflowEngine
'OCA\\WorkflowEngine\\Migration\\PopulateNewlyIntroducedDatabaseFields' => __DIR__ . '/..' . '/../lib/Migration/PopulateNewlyIntroducedDatabaseFields.php',
'OCA\\WorkflowEngine\\Migration\\Version2000Date20190808074233' => __DIR__ . '/..' . '/../lib/Migration/Version2000Date20190808074233.php',
'OCA\\WorkflowEngine\\Migration\\Version2200Date20210805101925' => __DIR__ . '/..' . '/../lib/Migration/Version2200Date20210805101925.php',
'OCA\\WorkflowEngine\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
'OCA\\WorkflowEngine\\Service\\Logger' => __DIR__ . '/..' . '/../lib/Service/Logger.php',
'OCA\\WorkflowEngine\\Service\\RuleMatcher' => __DIR__ . '/..' . '/../lib/Service/RuleMatcher.php',
'OCA\\WorkflowEngine\\Settings\\ASettings' => __DIR__ . '/..' . '/../lib/Settings/ASettings.php',

View file

@ -11,6 +11,8 @@ namespace OCA\WorkflowEngine\Controller;
use Doctrine\DBAL\Exception;
use OCA\WorkflowEngine\Helper\ScopeContext;
use OCA\WorkflowEngine\Manager;
use OCA\WorkflowEngine\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
@ -18,9 +20,16 @@ use OCP\AppFramework\OCS\OCSException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\AppFramework\OCSController;
use OCP\IRequest;
use OCP\WorkflowEngine\IEntityEvent;
use OCP\WorkflowEngine\IOperation;
use Psr\Log\LoggerInterface;
abstract class AWorkflowController extends OCSController {
/**
* @psalm-import-type WorkflowEngineOperator from ResponseDefinitions
* @psalm-import-type WorkflowEngineCheck from ResponseDefinitions
* @psalm-import-type WorkflowEngineRule from ResponseDefinitions
*/
abstract class AWorkflowOCSController extends OCSController {
public function __construct(
$appName,
@ -37,9 +46,11 @@ abstract class AWorkflowController extends OCSController {
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"
* Retrieve all configured workflow rules
*
* @throws OCSForbiddenException
* @return DataResponse<Http::STATUS_OK, array<class-string<IOperation>, list<WorkflowEngineRule>>, array{}>
*
* 200: List of workflows returned
*/
public function index(): DataResponse {
$operationsByClass = $this->manager->getAllOperations($this->getScopeContext());
@ -54,9 +65,12 @@ abstract class AWorkflowController extends OCSController {
}
/**
* 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"
* Retrieve a specific workflow
*
* @throws OCSForbiddenException
* @param string $id Workflow ID to load
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule|list<empty>, array{}>
*
* 200: Workflow returned or empty array if the ID is unknown in the scope
*/
public function show(string $id): DataResponse {
$context = $this->getScopeContext();
@ -72,9 +86,19 @@ abstract class AWorkflowController extends OCSController {
}
/**
* @throws OCSBadRequestException
* @throws OCSForbiddenException
* @throws OCSException
* Create a workflow
*
* @param class-string<IOperation> $class Operation class to execute
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation class to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow created
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
*/
#[PasswordConfirmationRequired]
public function create(
@ -101,9 +125,20 @@ abstract class AWorkflowController extends OCSController {
}
/**
* @throws OCSBadRequestException
* @throws OCSForbiddenException
* @throws OCSException
* Modify a workflow
*
* @param int $id Workflow ID to delete
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation action to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow updated
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[PasswordConfirmationRequired]
public function update(
@ -130,9 +165,14 @@ abstract class AWorkflowController extends OCSController {
}
/**
* @throws OCSBadRequestException
* @throws OCSForbiddenException
* @throws OCSException
* Delete a workflow
*
* @param int $id Workflow ID to delete
* @return DataResponse<Http::STATUS_OK, bool, array{}>|DataResponse<Http::STATUS_FORBIDDEN, list<empty>, array{}>
*
* 200: Workflow deleted
*
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[PasswordConfirmationRequired]
public function destroy(int $id): DataResponse {

View file

@ -9,12 +9,109 @@ declare(strict_types=1);
namespace OCA\WorkflowEngine\Controller;
use OCA\WorkflowEngine\Helper\ScopeContext;
use OCA\WorkflowEngine\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\WorkflowEngine\IEntityEvent;
use OCP\WorkflowEngine\IManager;
use OCP\WorkflowEngine\IOperation;
class GlobalWorkflowsController extends AWorkflowController {
/**
* @psalm-import-type WorkflowEngineCheck from ResponseDefinitions
* @psalm-import-type WorkflowEngineRule from ResponseDefinitions
*/
class GlobalWorkflowsController extends AWorkflowOCSController {
private ?ScopeContext $scopeContext = null;
/**
* Retrieve all configured workflow rules
*
* @return DataResponse<Http::STATUS_OK, array<class-string<IOperation>, list<WorkflowEngineRule>>, array{}>
*
* 200: List of workflows returned
*/
#[ApiRoute(verb: 'GET', url: '/api/v1/workflows/global')]
public function index(): DataResponse {
return parent::index();
}
/**
* Retrieve a specific workflow
*
* @param string $id Workflow ID to load
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule|list<empty>, array{}>
*
* 200: Workflow returned or empty array if the ID is unknown in the scope
*/
#[ApiRoute(verb: 'GET', url: '/api/v1/workflows/global/{id}')]
public function show(string $id): DataResponse {
return parent::show($id);
}
/**
* Create a workflow
*
* @param class-string<IOperation> $class Operation class to execute
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation class to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow created
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
*/
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'POST', url: '/api/v1/workflows/global')]
public function create(string $class, string $name, array $checks, string $operation, string $entity, array $events): DataResponse {
return parent::create($class, $name, $checks, $operation, $entity, $events);
}
/**
* Modify a workflow
*
* @param int $id Workflow ID to delete
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation action to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow updated
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'PUT', url: '/api/v1/workflows/global/{id}')]
public function update(int $id, string $name, array $checks, string $operation, string $entity, array $events): DataResponse {
return parent::update($id, $name, $checks, $operation, $entity, $events);
}
/**
* Delete a workflow
*
* @param int $id Workflow ID to delete
* @return DataResponse<Http::STATUS_OK, bool, array{}>|DataResponse<Http::STATUS_FORBIDDEN, list<empty>, array{}>
*
* 200: Workflow deleted
*
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'DELETE', url: '/api/v1/workflows/global/{id}')]
public function destroy(int $id): DataResponse {
return parent::destroy($id);
}
protected function getScopeContext(): ScopeContext {
if ($this->scopeContext === null) {
$this->scopeContext = new ScopeContext(IManager::SCOPE_ADMIN);

View file

@ -7,6 +7,7 @@
namespace OCA\WorkflowEngine\Controller;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\Attribute\FrontpageRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\JSONResponse;
@ -17,6 +18,7 @@ class RequestTimeController extends Controller {
* @return JSONResponse
*/
#[NoAdminRequired]
#[FrontpageRoute(verb: 'GET', url: '/timezones')]
public function getTimezones($search = '') {
$timezones = \DateTimeZone::listIdentifiers();

View file

@ -10,6 +10,9 @@ namespace OCA\WorkflowEngine\Controller;
use OCA\WorkflowEngine\Helper\ScopeContext;
use OCA\WorkflowEngine\Manager;
use OCA\WorkflowEngine\ResponseDefinitions;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\ApiRoute;
use OCP\AppFramework\Http\Attribute\NoAdminRequired;
use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
use OCP\AppFramework\Http\DataResponse;
@ -17,10 +20,16 @@ use OCP\AppFramework\OCS\OCSBadRequestException;
use OCP\AppFramework\OCS\OCSForbiddenException;
use OCP\IRequest;
use OCP\IUserSession;
use OCP\WorkflowEngine\IEntityEvent;
use OCP\WorkflowEngine\IManager;
use OCP\WorkflowEngine\IOperation;
use Psr\Log\LoggerInterface;
class UserWorkflowsController extends AWorkflowController {
/**
* @psalm-import-type WorkflowEngineCheck from ResponseDefinitions
* @psalm-import-type WorkflowEngineRule from ResponseDefinitions
*/
class UserWorkflowsController extends AWorkflowOCSController {
/** @var ScopeContext */
private $scopeContext;
@ -38,49 +47,88 @@ class UserWorkflowsController extends AWorkflowController {
/**
* 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"
* @return DataResponse<Http::STATUS_OK, array<class-string<IOperation>, list<WorkflowEngineRule>>, array{}>
*
* @throws OCSForbiddenException
* 200: List of workflows returned
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'GET', url: '/api/v1/workflows/user')]
public function index(): DataResponse {
return parent::index();
}
/**
* 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
* Retrieve a specific workflow
*
* @param string $id Workflow ID to load
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule|list<empty>, array{}>
*
* 200: Workflow returned or empty array if the ID is unknown in the scope
*/
#[NoAdminRequired]
#[ApiRoute(verb: 'GET', url: '/api/v1/workflows/user/{id}')]
public function show(string $id): DataResponse {
return parent::show($id);
}
/**
* @throws OCSBadRequestException
* @throws OCSForbiddenException
* Create a workflow
*
* @param class-string<IOperation> $class Operation class to execute
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation class to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow created
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
*/
#[NoAdminRequired]
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'POST', url: '/api/v1/workflows/user')]
public function create(string $class, string $name, array $checks, string $operation, string $entity, array $events): DataResponse {
return parent::create($class, $name, $checks, $operation, $entity, $events);
}
/**
* @throws OCSBadRequestException
* @throws OCSForbiddenException
* Modify a workflow
*
* @param int $id Workflow ID to delete
* @param string $name Name of the workflow rule
* @param list<WorkflowEngineCheck> $checks List of conditions that need to apply for the rule to match
* @param string $operation Operation action to execute on match
* @param string $entity The matched entity
* @param list<class-string<IEntityEvent>> $events The list of events on which the rule should be validated
* @return DataResponse<Http::STATUS_OK, WorkflowEngineRule, array{}>
*
* 200: Workflow updated
*
* @throws OCSBadRequestException Thrown when a check or check value is invalid
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[NoAdminRequired]
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'PUT', url: '/api/v1/workflows/user/{id}')]
public function update(int $id, string $name, array $checks, string $operation, string $entity, array $events): DataResponse {
return parent::update($id, $name, $checks, $operation, $entity, $events);
}
/**
* @throws OCSForbiddenException
* Delete a workflow
*
* @param int $id Workflow ID to delete
* @return DataResponse<Http::STATUS_OK, bool, array{}>|DataResponse<Http::STATUS_FORBIDDEN, list<empty>, array{}>
*
* 200: Workflow deleted
*
* @throws OCSForbiddenException Thrown when workflow is from a different scope
*/
#[NoAdminRequired]
#[PasswordConfirmationRequired]
#[ApiRoute(verb: 'DELETE', url: '/api/v1/workflows/user/{id}')]
public function destroy(int $id): DataResponse {
return parent::destroy($id);
}

View file

@ -43,13 +43,14 @@ use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
/**
* @psalm-type Check = array{id: int, class: class-string<ICheck>, operator: string, value: string, hash: string}
* @psalm-import-type WorkflowEngineCheck from ResponseDefinitions
* @psalm-import-type WorkflowEngineRule from ResponseDefinitions
*/
class Manager implements IManager {
/** @var array[] */
protected array $operations = [];
/** @var array<int, Check> */
/** @var array<int, WorkflowEngineCheck> */
protected array $checks = [];
/** @var IEntity[] */
@ -264,7 +265,7 @@ class Manager implements IManager {
/**
* @param string $class
* @param string $name
* @param list<Check> $checks
* @param list<WorkflowEngineCheck> $checks
* @param string $operation
* @return array The added operation
* @throws \UnexpectedValueException
@ -332,7 +333,7 @@ class Manager implements IManager {
/**
* @param int $id
* @param string $name
* @param array[] $checks
* @param list<WorkflowEngineCheck> $checks
* @param string $operation
* @return array The updated operation
* @throws \UnexpectedValueException
@ -455,7 +456,7 @@ class Manager implements IManager {
/**
* @param class-string<IOperation> $class
* @param list<Check> $checks
* @param list<WorkflowEngineCheck> $checks
* @param array $events
* @throws \UnexpectedValueException
*/
@ -522,7 +523,7 @@ class Manager implements IManager {
/**
* @param int[] $checkIds
* @return array<int, Check>
* @return array<int, WorkflowEngineCheck>
*/
public function getChecks(array $checkIds): array {
$checkIds = array_map('intval', $checkIds);
@ -546,9 +547,12 @@ class Manager implements IManager {
$result = $query->executeQuery();
while ($row = $result->fetchAssociative()) {
/** @var Check $row */
$this->checks[(int)$row['id']] = $row;
$checks[(int)$row['id']] = $row;
$id = (int)$row['id'];
unset($row['id'], $row['hash']);
/** @var WorkflowEngineCheck $row */
$this->checks[$id] = $row;
$checks[$id] = $row;
}
$result->closeCursor();
@ -604,20 +608,21 @@ class Manager implements IManager {
$insertQuery->executeStatement();
}
/**
* @param array{class: class-string<\OCP\WorkflowEngine\IOperation>, entity: class-string<\OCP\WorkflowEngine\IEntity>, checks: string, events: string, id: int, name: string, operation: string} $operation
* @return WorkflowEngineRule
*/
public function formatOperation(array $operation): array {
$checkIds = json_decode($operation['checks'], true);
/** @var list<WorkflowEngineCheck> $checks */
$checks = $this->getChecks($checkIds);
$operation['checks'] = $checks;
$operation['checks'] = [];
foreach ($checks as $check) {
// Remove internal values
unset($check['id']);
unset($check['hash']);
$operation['checks'][] = $check;
}
$operation['events'] = json_decode($operation['events'], true) ?? [];
/** @var list<class-string<IEntityEvent>> $events */
$events = json_decode($operation['events'], true) ?? [];
$operation['events'] = $events;
return $operation;
}

View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\WorkflowEngine;
use OCP\WorkflowEngine\ICheck;
use OCP\WorkflowEngine\IEntity;
use OCP\WorkflowEngine\IEntityEvent;
use OCP\WorkflowEngine\IOperation;
/**
* @psalm-type WorkflowEngineOperator = 'is'|'in'|'match'|'less'|'greater'|'matchesIPv4'|'matchesIPv6'|"!is"|"!in"|"!match"|"!less"|"!greater"|"!matchesIPv4"|"!matchesIPv6"
*
* @psalm-type WorkflowEngineCheck = array{
* class: class-string<ICheck>,
* value: string,
* operator: WorkflowEngineOperator,
* }
*
* @psalm-type WorkflowEngineRule = array{
* id: int,
* class: class-string<IOperation>,
* name: string,
* checks: list<WorkflowEngineCheck>,
* operation: string,
* entity: class-string<IEntity>,
* events: list<class-string<IEntityEvent>>,
* }
*/
class ResponseDefinitions {
}

View file

@ -11,6 +11,7 @@ namespace OCA\WorkflowEngine\Service;
use OCA\WorkflowEngine\Helper\LogContext;
use OCA\WorkflowEngine\Helper\ScopeContext;
use OCA\WorkflowEngine\Manager;
use OCA\WorkflowEngine\ResponseDefinitions;
use OCP\Files\Storage\IStorage;
use OCP\IL10N;
use OCP\IUserSession;
@ -26,7 +27,7 @@ use Psr\Container\ContainerInterface;
use RuntimeException;
/**
* @psalm-import-type Check from Manager
* @psalm-import-type WorkflowEngineCheck from ResponseDefinitions
*/
class RuleMatcher implements IRuleMatcher {
@ -179,7 +180,7 @@ class RuleMatcher implements IRuleMatcher {
}
/**
* @param Check $check
* @param WorkflowEngineCheck $check
* @return bool
*/
public function check(array $check): bool {

View file

@ -0,0 +1,967 @@
{
"openapi": "3.0.3",
"info": {
"title": "workflowengine-administration",
"version": "0.0.1",
"description": "Nextcloud workflow engine",
"license": {
"name": "agpl"
}
},
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
},
"bearer_auth": {
"type": "http",
"scheme": "bearer"
}
},
"schemas": {
"Check": {
"type": "object",
"required": [
"class",
"value",
"operator"
],
"properties": {
"class": {
"type": "string",
"minLength": 1
},
"value": {
"type": "string"
},
"operator": {
"$ref": "#/components/schemas/Operator"
}
}
},
"OCSMeta": {
"type": "object",
"required": [
"status",
"statuscode"
],
"properties": {
"status": {
"type": "string"
},
"statuscode": {
"type": "integer"
},
"message": {
"type": "string"
},
"totalitems": {
"type": "string"
},
"itemsperpage": {
"type": "string"
}
}
},
"Operator": {
"type": "string",
"enum": [
"is",
"in",
"match",
"less",
"greater",
"matchesIPv4",
"matchesIPv6",
"!is",
"!in",
"!match",
"!less",
"!greater",
"!matchesIPv4",
"!matchesIPv6"
]
},
"Rule": {
"type": "object",
"required": [
"id",
"class",
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"class": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"checks": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string"
},
"entity": {
"type": "string",
"minLength": 1
},
"events": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
},
"paths": {
"/ocs/v2.php/apps/workflowengine/api/v1/workflows/global": {
"get": {
"operationId": "global_workflows-index",
"summary": "Retrieve all configured workflow rules",
"description": "This endpoint requires admin access",
"tags": [
"global_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List of workflows returned",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "Logged in account must be an admin",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"post": {
"operationId": "global_workflows-create",
"summary": "Create a workflow",
"description": "This endpoint requires admin access\nThis endpoint requires password confirmation",
"tags": [
"global_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"class",
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"class": {
"type": "string",
"description": "Operation class to execute",
"minLength": 1
},
"name": {
"type": "string",
"description": "Name of the workflow rule"
},
"checks": {
"type": "array",
"description": "List of conditions that need to apply for the rule to match",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string",
"description": "Operation class to execute on match"
},
"entity": {
"type": "string",
"description": "The matched entity"
},
"events": {
"type": "array",
"description": "The list of events on which the rule should be validated",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
},
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
},
"400": {
"description": "Thrown when a check or check value is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "Logged in account must be an admin",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/workflowengine/api/v1/workflows/global/{id}": {
"get": {
"operationId": "global_workflows-show",
"summary": "Retrieve a specific workflow",
"description": "This endpoint requires admin access",
"tags": [
"global_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to load",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow returned or empty array if the ID is unknown in the scope",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"anyOf": [
{
"$ref": "#/components/schemas/Rule"
},
{
"type": "array",
"maxItems": 0
}
]
}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "Logged in account must be an admin",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"put": {
"operationId": "global_workflows-update",
"summary": "Modify a workflow",
"description": "This endpoint requires admin access\nThis endpoint requires password confirmation",
"tags": [
"global_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the workflow rule"
},
"checks": {
"type": "array",
"description": "List of conditions that need to apply for the rule to match",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string",
"description": "Operation action to execute on match"
},
"entity": {
"type": "string",
"description": "The matched entity"
},
"events": {
"type": "array",
"description": "The list of events on which the rule should be validated",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to delete",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
},
"400": {
"description": "Thrown when a check or check value is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "Thrown when workflow is from a different scope",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
},
{
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
]
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"delete": {
"operationId": "global_workflows-destroy",
"summary": "Delete a workflow",
"description": "This endpoint requires admin access\nThis endpoint requires password confirmation",
"tags": [
"global_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to delete",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "boolean"
}
}
}
}
}
}
}
},
"403": {
"description": "Thrown when workflow is from a different scope",
"content": {
"application/json": {
"schema": {
"anyOf": [
{
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
},
{
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
]
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
}
},
"tags": []
}

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
SPDX-License-Identifier: AGPL-3.0-or-later

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
SPDX-License-Identifier: AGPL-3.0-or-later

View file

@ -0,0 +1,831 @@
{
"openapi": "3.0.3",
"info": {
"title": "workflowengine",
"version": "0.0.1",
"description": "Nextcloud workflow engine",
"license": {
"name": "agpl"
}
},
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
},
"bearer_auth": {
"type": "http",
"scheme": "bearer"
}
},
"schemas": {
"Check": {
"type": "object",
"required": [
"class",
"value",
"operator"
],
"properties": {
"class": {
"type": "string",
"minLength": 1
},
"value": {
"type": "string"
},
"operator": {
"$ref": "#/components/schemas/Operator"
}
}
},
"OCSMeta": {
"type": "object",
"required": [
"status",
"statuscode"
],
"properties": {
"status": {
"type": "string"
},
"statuscode": {
"type": "integer"
},
"message": {
"type": "string"
},
"totalitems": {
"type": "string"
},
"itemsperpage": {
"type": "string"
}
}
},
"Operator": {
"type": "string",
"enum": [
"is",
"in",
"match",
"less",
"greater",
"matchesIPv4",
"matchesIPv6",
"!is",
"!in",
"!match",
"!less",
"!greater",
"!matchesIPv4",
"!matchesIPv6"
]
},
"Rule": {
"type": "object",
"required": [
"id",
"class",
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"class": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string"
},
"checks": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string"
},
"entity": {
"type": "string",
"minLength": 1
},
"events": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
},
"paths": {
"/ocs/v2.php/apps/workflowengine/api/v1/workflows/user": {
"get": {
"operationId": "user_workflows-index",
"summary": "Retrieve all configured workflow rules",
"tags": [
"user_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "List of workflows returned",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"post": {
"operationId": "user_workflows-create",
"summary": "Create a workflow",
"description": "This endpoint requires password confirmation",
"tags": [
"user_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"class",
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"class": {
"type": "string",
"description": "Operation class to execute",
"minLength": 1
},
"name": {
"type": "string",
"description": "Name of the workflow rule"
},
"checks": {
"type": "array",
"description": "List of conditions that need to apply for the rule to match",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string",
"description": "Operation class to execute on match"
},
"entity": {
"type": "string",
"description": "The matched entity"
},
"events": {
"type": "array",
"description": "The list of events on which the rule should be validated",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
},
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow created",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
},
"400": {
"description": "Thrown when a check or check value is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/workflowengine/api/v1/workflows/user/{id}": {
"get": {
"operationId": "user_workflows-show",
"summary": "Retrieve a specific workflow",
"tags": [
"user_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to load",
"required": true,
"schema": {
"type": "string"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow returned or empty array if the ID is unknown in the scope",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"anyOf": [
{
"$ref": "#/components/schemas/Rule"
},
{
"type": "array",
"maxItems": 0
}
]
}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"put": {
"operationId": "user_workflows-update",
"summary": "Modify a workflow",
"description": "This endpoint requires password confirmation",
"tags": [
"user_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"checks",
"operation",
"entity",
"events"
],
"properties": {
"name": {
"type": "string",
"description": "Name of the workflow rule"
},
"checks": {
"type": "array",
"description": "List of conditions that need to apply for the rule to match",
"items": {
"$ref": "#/components/schemas/Check"
}
},
"operation": {
"type": "string",
"description": "Operation action to execute on match"
},
"entity": {
"type": "string",
"description": "The matched entity"
},
"events": {
"type": "array",
"description": "The list of events on which the rule should be validated",
"items": {
"type": "string",
"minLength": 1
}
}
}
}
}
}
},
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to delete",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow updated",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"$ref": "#/components/schemas/Rule"
}
}
}
}
}
}
}
},
"400": {
"description": "Thrown when a check or check value is invalid",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"403": {
"description": "Thrown when workflow is from a different scope",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
},
"delete": {
"operationId": "user_workflows-destroy",
"summary": "Delete a workflow",
"description": "This endpoint requires password confirmation",
"tags": [
"user_workflows"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"description": "Workflow ID to delete",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Workflow deleted",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "boolean"
}
}
}
}
}
}
}
},
"403": {
"description": "Thrown when workflow is from a different scope",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
},
"401": {
"description": "Current user is not logged in",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {}
}
}
}
}
}
}
}
}
}
}
},
"tags": []
}

View file

@ -0,0 +1,2 @@
SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
SPDX-License-Identifier: AGPL-3.0-or-later

File diff suppressed because it is too large Load diff