summaryrefslogtreecommitdiffstats
path: root/apps/workflowengine
diff options
context:
space:
mode:
authorblizzz <blizzz@arthur-schiwon.de>2020-10-28 16:05:35 +0100
committerGitHub <noreply@github.com>2020-10-28 16:05:35 +0100
commit6b2cf46125343ab184e50a51cea08813f5b50997 (patch)
treed9b390c046e1b69ec46b134d298beccf0553ae7c /apps/workflowengine
parent4ade7f12f263f9702fd801b483603c0005ff2d34 (diff)
parent1eb86e46fdfaed73d240b3e47b6fe9a36179b3a5 (diff)
downloadnextcloud-server-6b2cf46125343ab184e50a51cea08813f5b50997.tar.gz
nextcloud-server-6b2cf46125343ab184e50a51cea08813f5b50997.zip
Merge pull request #23752 from nextcloud/fix/noid/wfe-ux-errors
inform the user when flow config data exceeds thresholds
Diffstat (limited to 'apps/workflowengine')
-rw-r--r--apps/workflowengine/lib/Manager.php9
-rw-r--r--apps/workflowengine/tests/ManagerTest.php159
2 files changed, 168 insertions, 0 deletions
diff --git a/apps/workflowengine/lib/Manager.php b/apps/workflowengine/lib/Manager.php
index c949e7f36f7..87c3c5de6b3 100644
--- a/apps/workflowengine/lib/Manager.php
+++ b/apps/workflowengine/lib/Manager.php
@@ -492,6 +492,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) {
@@ -516,6 +521,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 0022fc37cb9..1aaa3b1a3c5 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;
@@ -435,4 +436,162 @@ class ManagerTest extends TestCase {
$this->assertSame(1, $entityTypeCounts[0]);
$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());
+ }
+ }
}