From 37179dc8ec179808a5ec6400b8775ec313c336f8 Mon Sep 17 00:00:00 2001 From: stonebuzz Date: Thu, 6 Jun 2024 14:04:03 +0200 Subject: [PATCH] Fix(Rule): do not import locations in preview mode --- src/Rule.php | 13 ++++++- src/RuleLocation.php | 12 +++++-- tests/functional/RuleLocation.php | 58 +++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 4 deletions(-) diff --git a/src/Rule.php b/src/Rule.php index b80c9390179..9b35aa13138 100644 --- a/src/Rule.php +++ b/src/Rule.php @@ -55,6 +55,8 @@ class Rule extends CommonDBTM public $criterias = []; /// Rules can be sorted ? public $can_sort = false; + // preview context ? + protected $is_preview = false; /// field used to order rules public $orderby = 'ranking'; @@ -2195,11 +2197,13 @@ public function showMinimalActionForm($fields, $canedit, $rand) **/ public function showRulePreviewResultsForm($target, $input, $params) { - $actions = $this->getAllActions(); $check_results = []; $output = []; + // specify that we are in a test context + $this->is_preview = true; + //Test all criteria, without stopping at the first good one $this->testCriterias($input, $check_results); //Process the rule @@ -2690,6 +2694,13 @@ public function getActionValue($ID, $type, $value) return $this->displayAdditionRuleActionValue($value); } + if ($this->is_preview && !is_numeric($value)) { + // In preview mode, if the value corresponds to a string + // that does not match an existing dropdown entry, + // it will not be imported and therefore tha value will not correspond to a dropdown valid ID. + return $value; + } + // $type == assign $name = Dropdown::getDropdownName($action["table"], $value); return (($name == ' ') ? NOT_AVAILABLE : $name); diff --git a/src/RuleLocation.php b/src/RuleLocation.php index 8d43169859c..7459ffb280f 100644 --- a/src/RuleLocation.php +++ b/src/RuleLocation.php @@ -64,9 +64,15 @@ public function executeActions($output, $params, array $input = []) $action->fields["value"], $regex_result ); - $compute_entities_id = $input['entities_id'] ?? 0; - $location = new Location(); - $output['locations_id'] = $location->importExternal($regexvalue, $compute_entities_id); + + // from rule test context just assign regex value to key + if ($this->is_preview) { + $output['locations_id'] = $regexvalue; + } else { + $compute_entities_id = $input['entities_id'] ?? 0; + $location = new Location(); + $output['locations_id'] = $location->importExternal($regexvalue, $compute_entities_id); + } } } break; diff --git a/tests/functional/RuleLocation.php b/tests/functional/RuleLocation.php index 2db08946908..d9d7bc9fd04 100644 --- a/tests/functional/RuleLocation.php +++ b/tests/functional/RuleLocation.php @@ -349,4 +349,62 @@ public function testSubIPCIDR() $all_locations = getAllDataFromTable($location->getTable()); $this->integer(count($all_locations))->isIdenticalTo($count_locations); } + + + public function testActionsFromTestContext() + { + $this->login(); + + $location = new \Location(); + $locations_id = $location->add([ + 'name' => 'Location_Test', + ]); + $this->integer($locations_id)->isGreaterThan(0); + + $rule = new \Rule(); + $input = [ + 'is_active' => 1, + 'name' => 'location rule test context', + 'match' => 'AND', + 'sub_type' => 'RuleLocation', + 'ranking' => 1 + ]; + $rules_id = $rule->add($input); + $this->integer($rules_id)->isGreaterThan(0); + + $rulecriteria = new \RuleCriteria(); + $input = [ + 'rules_id' => $rules_id, + 'criteria' => "tag", + 'pattern' => "/(.*)/", + 'condition' => \RuleImportEntity::REGEX_MATCH + ]; + $this->integer($rulecriteria->add($input))->isGreaterThan(0); + + $ruleaction = new \RuleAction(); + $input = [ + 'rules_id' => $rules_id, + 'action_type' => 'regex_result', + 'field' => 'locations_id', + 'value' => "#0" + ]; + $this->integer($ruleaction->add($input))->isGreaterThan(0); + + // test rule like rule.test.php + $rule = new \RuleLocation(); + $rule->getRuleWithCriteriasAndActions($rules_id, 1, 1); + + $params = $rule->addSpecificParamsForPreview([]); + $input = $rule->prepareAllInputDataForProcess(['tag' => 'testtag'], $params); + + // intercepts the output of echo functions + // as showRulePreviewResultsForm is also in charge of displaying the result (in addition to testing the rule) + ob_start(); + $rule->showRulePreviewResultsForm($_SERVER['PHP_SELF'], $input, $params); + ob_end_clean(); + + // check that location was not created + $location = new \Location(); + $this->boolean($location->getFromDBByCrit(['name' => 'testtag']))->isNotTrue(); + } }