Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur Schiwon <blizzz@arthur-schiwon.de>2020-10-28 16:07:14 +0300
committerArthur Schiwon <blizzz@arthur-schiwon.de>2020-11-09 20:15:02 +0300
commit793a52dd1413eac19fc299c153824700add26cdf (patch)
treeb4ef0f8875caacc3f7b172e2c1c88312faff404a
parentc6abcfbbfa658977b70e9a36d2dc3e8931829767 (diff)
inform the user when flow config data exceeds thresholds
Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
-rw-r--r--apps/workflowengine/lib/Manager.php9
-rw-r--r--apps/workflowengine/tests/ManagerTest.php159
-rw-r--r--lib/public/WorkflowEngine/IManager.php10
3 files changed, 178 insertions, 0 deletions
diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php
index 5bb9704e291..136e80e0bc7 100644
--- a/apps/workflowengine/lib/Manager.php
+++ b/apps/workflowengine/lib/Manager.php
@@ -488,6 +488,11 @@ class Manager implements IManager {
if (count($checks) === 0) {
throw new \UnexpectedValueException($this->l->t('At least one check needs to be provided'));
}
+
+ if (strlen((string)$operation) > IManager::MAX_OPERATION_VALUE_BYTES) {
+ throw new \UnexpectedValueException($this->l->t('The provided operation data is too long'));
+ }
+
$instance->validateOperation($name, $checks, $operation);
foreach ($checks as $check) {
@@ -512,6 +517,10 @@ class Manager implements IManager {
throw new \UnexpectedValueException($this->l->t('Check %s is not allowed with this entity', [$class]));
}
+ if (strlen((string)$check['value']) > IManager::MAX_CHECK_VALUE_BYTES) {
+ throw new \UnexpectedValueException($this->l->t('The provided check value is too long'));
+ }
+
$instance->validateCheck($check['operator'], $check['value']);
}
}
diff --git a/apps/workflowengine/tests/ManagerTest.php b/apps/workflowengine/tests/ManagerTest.php
index 28001a05a92..b81b2d648ed 100644
--- a/apps/workflowengine/tests/ManagerTest.php
+++ b/apps/workflowengine/tests/ManagerTest.php
@@ -38,6 +38,7 @@ use OCP\IUserSession;
use OCP\SystemTag\ISystemTagManager;
use OCP\WorkflowEngine\ICheck;
use OCP\WorkflowEngine\IEntity;
+use OCP\WorkflowEngine\IEntityEvent;
use OCP\WorkflowEngine\IManager;
use OCP\WorkflowEngine\IOperation;
use PHPUnit\Framework\MockObject\MockObject;
@@ -433,4 +434,162 @@ class ManagerTest extends TestCase {
$this->assertSame(1, $entityTypeCounts[1]);
}
+ public function testValidateOperationOK() {
+ $check = [
+ 'class' => ICheck::class,
+ 'operator' => 'is',
+ 'value' => 'barfoo',
+ ];
+
+ $operationMock = $this->createMock(IOperation::class);
+ $entityMock = $this->createMock(IEntity::class);
+ $eventEntityMock = $this->createMock(IEntityEvent::class);
+ $checkMock = $this->createMock(ICheck::class);
+
+ $operationMock->expects($this->once())
+ ->method('validateOperation')
+ ->with('test', [$check], 'operationData');
+
+ $entityMock->expects($this->any())
+ ->method('getEvents')
+ ->willReturn([$eventEntityMock]);
+
+ $eventEntityMock->expects($this->any())
+ ->method('getEventName')
+ ->willReturn('MyEvent');
+
+ $checkMock->expects($this->any())
+ ->method('supportedEntities')
+ ->willReturn([IEntity::class]);
+ $checkMock->expects($this->atLeastOnce())
+ ->method('validateCheck');
+
+ $this->container->expects($this->any())
+ ->method('query')
+ ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
+ switch ($className) {
+ case IOperation::class:
+ return $operationMock;
+ case IEntity::class:
+ return $entityMock;
+ case IEntityEvent::class:
+ return $eventEntityMock;
+ case ICheck::class:
+ return $checkMock;
+ default:
+ return $this->createMock($className);
+ }
+ });
+
+ $this->manager->validateOperation(IOperation::class, 'test', [$check], 'operationData', IEntity::class, ['MyEvent']);
+ }
+
+ public function testValidateOperationCheckInputLengthError() {
+ $check = [
+ 'class' => ICheck::class,
+ 'operator' => 'is',
+ 'value' => str_pad('', IManager::MAX_CHECK_VALUE_BYTES + 1, 'FooBar'),
+ ];
+
+ $operationMock = $this->createMock(IOperation::class);
+ $entityMock = $this->createMock(IEntity::class);
+ $eventEntityMock = $this->createMock(IEntityEvent::class);
+ $checkMock = $this->createMock(ICheck::class);
+
+ $operationMock->expects($this->once())
+ ->method('validateOperation')
+ ->with('test', [$check], 'operationData');
+
+ $entityMock->expects($this->any())
+ ->method('getEvents')
+ ->willReturn([$eventEntityMock]);
+
+ $eventEntityMock->expects($this->any())
+ ->method('getEventName')
+ ->willReturn('MyEvent');
+
+ $checkMock->expects($this->any())
+ ->method('supportedEntities')
+ ->willReturn([IEntity::class]);
+ $checkMock->expects($this->never())
+ ->method('validateCheck');
+
+ $this->container->expects($this->any())
+ ->method('query')
+ ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
+ switch ($className) {
+ case IOperation::class:
+ return $operationMock;
+ case IEntity::class:
+ return $entityMock;
+ case IEntityEvent::class:
+ return $eventEntityMock;
+ case ICheck::class:
+ return $checkMock;
+ default:
+ return $this->createMock($className);
+ }
+ });
+
+ try {
+ $this->manager->validateOperation(IOperation::class, 'test', [$check], 'operationData', IEntity::class, ['MyEvent']);
+ } catch (\UnexpectedValueException $e) {
+ $this->assertSame('The provided check value is too long', $e->getMessage());
+ }
+ }
+
+ public function testValidateOperationDataLengthError() {
+ $check = [
+ 'class' => ICheck::class,
+ 'operator' => 'is',
+ 'value' => 'barfoo',
+ ];
+ $operationData = str_pad('', IManager::MAX_OPERATION_VALUE_BYTES + 1, 'FooBar');
+
+ $operationMock = $this->createMock(IOperation::class);
+ $entityMock = $this->createMock(IEntity::class);
+ $eventEntityMock = $this->createMock(IEntityEvent::class);
+ $checkMock = $this->createMock(ICheck::class);
+
+ $operationMock->expects($this->never())
+ ->method('validateOperation');
+
+ $entityMock->expects($this->any())
+ ->method('getEvents')
+ ->willReturn([$eventEntityMock]);
+
+ $eventEntityMock->expects($this->any())
+ ->method('getEventName')
+ ->willReturn('MyEvent');
+
+ $checkMock->expects($this->any())
+ ->method('supportedEntities')
+ ->willReturn([IEntity::class]);
+ $checkMock->expects($this->never())
+ ->method('validateCheck');
+
+ $this->container->expects($this->any())
+ ->method('query')
+ ->willReturnCallback(function ($className) use ($operationMock, $entityMock, $eventEntityMock, $checkMock) {
+ switch ($className) {
+ case IOperation::class:
+ return $operationMock;
+ case IEntity::class:
+ return $entityMock;
+ case IEntityEvent::class:
+ return $eventEntityMock;
+ case ICheck::class:
+ return $checkMock;
+ default:
+ return $this->createMock($className);
+ }
+ });
+
+ try {
+ $this->manager->validateOperation(IOperation::class, 'test', [$check], $operationData, IEntity::class, ['MyEvent']);
+ } catch (\UnexpectedValueException $e) {
+ $this->assertSame('The provided operation data is too long', $e->getMessage());
+ }
+ }
+
}
diff --git a/lib/public/WorkflowEngine/IManager.php b/lib/public/WorkflowEngine/IManager.php
index 490467663ae..5956228ce7e 100644
--- a/lib/public/WorkflowEngine/IManager.php
+++ b/lib/public/WorkflowEngine/IManager.php
@@ -35,6 +35,16 @@ interface IManager {
const SCOPE_USER = 1;
/**
+ * @since 21.0.0
+ */
+ public const MAX_CHECK_VALUE_BYTES = 2048;
+
+ /**
+ * @since 21.0.0
+ */
+ public const MAX_OPERATION_VALUE_BYTES = 4096;
+
+ /**
* @depreacted Will be removed in NC19. Use the dedicated events in OCP\WorkflowEngine\Events
*/
const EVENT_NAME_REG_OPERATION = 'OCP\WorkflowEngine::registerOperations';