From cf4fa70cd24a09dd7729420809c1968f030c0a5c Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Wed, 20 Mar 2024 11:38:53 +0100 Subject: [PATCH] net/relayd - move validation responsibility to the model, for https://github.com/opnsense/plugins/issues/3850 @fbrendel fyi --- .../Relayd/Api/SettingsController.php | 92 +--------------- .../mvc/app/models/OPNsense/Relayd/Relayd.php | 102 ++++++++++++++++++ 2 files changed, 105 insertions(+), 89 deletions(-) diff --git a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php index c47153d92..fee390f1f 100644 --- a/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php +++ b/net/relayd/src/opnsense/mvc/app/controllers/OPNsense/Relayd/Api/SettingsController.php @@ -98,7 +98,7 @@ class SettingsController extends ApiMutableModelControllerBase */ public function setAction($nodeType = null, $uuid = null) { - $result = array('result' => 'failed', 'validations' => array()); + $result = array('result' => 'failed', 'validations' => []); if ($this->request->isPost() && $this->request->hasPost('relayd') && $nodeType != null) { $this->validateNodeType($nodeType); if ($nodeType == 'general') { @@ -111,93 +111,7 @@ class SettingsController extends ApiMutableModelControllerBase } } if ($node != null) { - $relaydInfo = $this->request->getPost('relayd'); - - // perform plugin specific validations - if ($nodeType == 'virtualserver') { - // preset defaults for validations - if (empty($relaydInfo[$nodeType]['type'])) { - $relaydInfo[$nodeType]['type'] = $node->type->__toString(); - } - if (empty($relaydInfo[$nodeType]['transport_tablemode'])) { - $relaydInfo[$nodeType]['transport_tablemode'] = $node->transport_tablemode->__toString(); - } - if (empty($relaydInfo[$nodeType]['backuptransport_tablemode'])) { - $relaydInfo[$nodeType]['backuptransport_tablemode'] = - $node->backuptransport_tablemode->__toString(); - } - - if ($relaydInfo[$nodeType]['type'] == 'redirect') { - if ( - $relaydInfo[$nodeType]['transport_tablemode'] != 'least-states' && - $relaydInfo[$nodeType]['transport_tablemode'] != 'roundrobin' - ) { - $result['validations']['relayd.virtualserver.transport_tablemode'] = sprintf( - gettext('Scheduler "%s" not supported for redirects.'), - $relaydInfo[$nodeType]['transport_tablemode'] - ); - } - if ( - $relaydInfo[$nodeType]['backuptransport_tablemode'] != 'least-states' && - $relaydInfo[$nodeType]['backuptransport_tablemode'] != 'roundrobin' - ) { - $result['validations']['relayd.virtualserver.backuptransport_tablemode'] = sprintf( - gettext('Scheduler "%s" not supported for redirects.'), - $relaydInfo[$nodeType]['backuptransport_tablemode'] - ); - } - if ( - $relaydInfo[$nodeType]['transport_type'] == 'route' && - empty($relaydInfo[$nodeType]['routing_interface']) - ) { - $result['validations']['relayd.virtualserver.routing_interface'] = - gettext('Routing interface cannot be empty'); - } - } - if ($relaydInfo[$nodeType]['type'] == 'relay') { - if ($relaydInfo[$nodeType]['transport_tablemode'] == 'least-states') { - $result['validations']['relayd.virtualserver.transport_tablemode'] = sprintf( - gettext('Scheduler "%s" not supported for relays.'), - $relaydInfo[$nodeType]['transport_tablemode'] - ); - } - if ($relaydInfo[$nodeType]['backuptransport_tablemode'] == 'least-states') { - $result['validations']['relayd.virtualserver.backuptransport_tablemode'] = sprintf( - gettext('Scheduler "%s" not supported for relays.'), - $relaydInfo[$nodeType]['backuptransport_tablemode'] - ); - } - } - } elseif ($nodeType == 'tablecheck') { - switch ($relaydInfo[$nodeType]['type']) { - case 'send': - if (empty($relaydInfo[$nodeType]['expect'])) { - $result['validations']['relayd.tablecheck.expect'] = - gettext('Expect Pattern cannot be empty.'); - } - break; - case 'script': - if (empty($relaydInfo[$nodeType]['path'])) { - $result['validations']['relayd.tablecheck.path'] = - gettext('Script path cannot be empty.'); - } - break; - case 'http': - if (empty($relaydInfo[$nodeType]['path'])) { - $result['validations']['relayd.tablecheck.path'] = - gettext('Path cannot be empty.'); - } - if (empty($relaydInfo[$nodeType]['code']) && empty($relaydInfo[$nodeType]['digest'])) { - $result['validations']['relayd.tablecheck.code'] = - gettext('Provide one of Response Code or Message Digest.'); - $result['validations']['relayd.tablecheck.digest'] = - gettext('Provide one of Response Code or Message Digest.'); - } - break; - } - } - - $node->setNodes($relaydInfo[$nodeType]); + $node->setNodes($this->request->getPost('relayd')[$nodeType]); $valMsgs = $this->getModel()->performValidation(); foreach ($valMsgs as $field => $msg) { $fieldnm = str_replace($node->__reference, "relayd." . $nodeType, $msg->getField()); @@ -330,7 +244,7 @@ class SettingsController extends ApiMutableModelControllerBase if ($this->request->isPost() && $nodeType != null) { $this->validateNodeType($nodeType); $grid = new UIModelGrid($this->getModel()->$nodeType); - $fields = array(); + $fields = []; switch ($nodeType) { case 'host': $fields = ['enabled', 'name', 'address']; diff --git a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php index 0669849ed..37e495b0f 100644 --- a/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php +++ b/net/relayd/src/opnsense/mvc/app/models/OPNsense/Relayd/Relayd.php @@ -31,6 +31,7 @@ namespace OPNsense\Relayd; use OPNsense\Base\BaseModel; +use OPNsense\Base\Messages\Message; /** * Class Relayd @@ -65,6 +66,107 @@ class Relayd extends BaseModel return @unlink("/tmp/relayd.dirty"); } + /** + * {@inheritdoc} + */ + public function performValidation($validateFullModel = false) + { + $messages = parent::performValidation($validateFullModel); + foreach ($this->virtualserver->iterateItems() as $node) { + if (!$validateFullModel && !$node->isFieldChanged()) { + continue; + } + $key = $node->__reference; + if ($node->type == 'redirect') { + if (!in_array((string)$node->transport_tablemode, ['least-states', 'roundrobin'])) { + $messages->appendMessage( + new Message( + sprintf(gettext('Scheduler "%s" not supported for redirects.'), $node->transport_tablemode), + $key . ".transport_tablemode" + ) + ); + } + if (!in_array((string)$node->backuptransport_tablemode, ['least-states', 'roundrobin'])) { + $messages->appendMessage( + new Message( + sprintf(gettext('Scheduler "%s" not supported for redirects.'), $node->transport_tablemode), + $key . ".backuptransport_tablemode" + ) + ); + } + if ($node->transport_type == 'route' && empty((string)$node->routing_interface)) { + $messages->appendMessage( + new Message(gettext('Routing interface cannot be empty'), $key . ".routing_interface") + ); + } + } elseif ($node->type == 'relay') { + if ($node->transport_tablemode == 'least-states') { + $messages->appendMessage( + new Message( + sprintf(gettext('Scheduler "%s" not supported for relays.'), $node->transport_tablemode), + $key . ".transport_tablemode" + ) + ); + } + if ($node->backuptransport_tablemode == 'least-states') { + $messages->appendMessage( + new Message( + sprintf( + gettext('Scheduler "%s" not supported for relays.'), + $node->backuptransport_tablemode + ), + $key . ".backuptransport_tablemode" + ) + ); + } + } + foreach ($this->tablecheck->iterateItems() as $node) { + if (!$validateFullModel && !$node->isFieldChanged()) { + continue; + } + $key = $node->__reference; + switch ((string)$node->type) { + case 'send': + if (empty((string)$node->expect)) { + $messages->appendMessage( + new Message(gettext('Expect Pattern cannot be empty.'), $key . ".expect") + ); + } + break; + case 'script': + if (empty((string)$node->path)) { + $messages->appendMessage( + new Message(gettext('Script path cannot be empty.'), $key . ".path") + ); + } + break; + case 'http': + if (empty((string)$node->path)) { + $messages->appendMessage( + new Message(gettext('Path cannot be empty.'), $key . ".path") + ); + } + if (empty((string)$node->code) && empty((string)$node->digest)) { + $messages->appendMessage( + new Message( + gettext('Provide one of Response Code or Message Digest.'), + $key . ".code" + ) + ); + $messages->appendMessage( + new Message( + gettext('Provide one of Response Code or Message Digest.'), + $key . ".digest" + ) + ); + } + break; + } + } + } + return $messages; + } + /** * @param string $type type of object (host, table, virtualserver) * @param string $name name of the attribute