From d08da5ca8c981aa15088c80c7f01ed5d3c535adf Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Thu, 12 Nov 2020 14:57:57 -0700 Subject: [PATCH] [Security Solutions] Adds a default for indicator match custom query of *:* (#81727) ## Summary Allows for Indicator matches to have a default of `*:*` for the query field when it is selected. Before, indicator query is blank when first selecting the rule: Screen Shot 2020-11-05 at 5 44 50 PM After, indicator query is by default `*:*` unless the user has previously edited the query field: Screen Shot 2020-11-05 at 5 45 38 PM Adds a stable reference for threat matching to determine when the query field has been modified or not. This is keep the current behavior and the rules operate like this: * If you select an indicator match rule and nothing has been previously edited it will select `*:*` for the query * If you have modified your custom query and select indicator match rule, then `*:*` will be replaced with that custom query and `*:*` will not be used. * If you select EQL rule and then _back_ to this rule type the `*:*` will be re-inserted and `edit: true` will flip back to false, due to the magic that is keys within React and how the EQL rule type relies on that. ### Checklist Delete any items that are not applicable to this PR. - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --- .../rules/step_define_rule/index.tsx | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx index 8a5966c71aa28..f06d4bdef74cb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_define_rule/index.tsx @@ -88,6 +88,17 @@ const stepDefineDefaultValue: DefineStepRule = { }, }; +/** + * This default query will be used for threat query/indicator matches + * as the default when the user swaps to using it by changing their + * rule type from any rule type to the "threatMatchRule" type. Only + * difference is that "*:*" is used instead of '' for its query. + */ +const threatQueryBarDefaultValue: DefineStepRule['queryBar'] = { + ...stepDefineDefaultValue.queryBar, + query: { ...stepDefineDefaultValue.queryBar.query, query: '*:*' }, +}; + const MyLabelButton = styled(EuiButtonEmpty)` height: 18px; font-size: 12px; @@ -171,6 +182,38 @@ const StepDefineRuleComponent: FC = ({ setIndexModified(!isEqual(index, indicesConfig)); }, [index, indicesConfig]); + /** + * When a rule type is changed to or from a threat match this will modify the + * default query string to either: + * * from the empty string '' to '*:*' if the rule type is "threatMatchRule" + * * from '*:*' back to the empty string '' if the rule type is not "threatMatchRule" + * This calls queryBar.reset() in both cases to not trigger validation errors as + * the user has not entered data into those areas yet. + * If the user has entered data then through reference compares we can detect reliably if + * the user has changed data. + * * queryBar.value === defaultQueryBar (Has the user changed the input of '' yet?) + * * queryBar.value === threatQueryBarDefaultValue (Has the user changed the input of '*:*' yet?) + * This is a stronger guarantee than "isPristine" off of the forms as that value can be reset + * if you go to step 2) and then back to step 1) or the form is reset in another way. Using + * the reference compare we know factually if the data is changed as the references must change + * in the form libraries form the initial defaults. + */ + useEffect(() => { + const { queryBar } = getFields(); + if (queryBar != null) { + const { queryBar: defaultQueryBar } = stepDefineDefaultValue; + if (isThreatMatchRule(ruleType) && queryBar.value === defaultQueryBar) { + queryBar.reset({ + defaultValue: threatQueryBarDefaultValue, + }); + } else if (queryBar.value === threatQueryBarDefaultValue) { + queryBar.reset({ + defaultValue: defaultQueryBar, + }); + } + } + }, [ruleType, getFields]); + const handleSubmit = useCallback(() => { if (onSubmit) { onSubmit();