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:
authorMorris Jobke <hey@morrisjobke.de>2020-10-29 10:54:25 +0300
committerGitHub <noreply@github.com>2020-10-29 10:54:25 +0300
commitbbc586a1e44063bfc1408ce678edf42b417e997b (patch)
tree7f9f0a3c9667362ef77ff819b555782c8631e6ac /apps/workflowengine
parentc0662a9d46cde5ea6ae792ce8d95b8992abedaf2 (diff)
parent4967d5b2babb4013b052053239415e5f886a1121 (diff)
Merge pull request #23760 from nextcloud/backport/23752/stable19
[stable19] 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 fefeb9230e6..f3cf7621058 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 512d5dc1f61..7d22e910b6d 100644
--- a/apps/workflowengine/tests/ManagerTest.php
+++ b/apps/workflowengine/tests/ManagerTest.php
@@ -37,6 +37,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[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());
+ }
+ }
}