diff --git a/models/interfaces.ts b/models/interfaces.ts index a2982c8fc..3c393422f 100644 --- a/models/interfaces.ts +++ b/models/interfaces.ts @@ -9,11 +9,11 @@ export interface Rule { log_source: string; title: string; description: string; - tags: { value: string }[]; - false_positives: { value: string }[]; + tags: Array<{ value: string }>; + false_positives: Array<{ value: string }>; level: string; status: string; - references: { value: string }[]; + references: Array<{ value: string }>; author: string; detection: string; } diff --git a/public/pages/Rules/components/RuleEditor/RuleEditor.tsx b/public/pages/Rules/components/RuleEditor/RuleEditor.tsx index ca4fef832..d6a354770 100644 --- a/public/pages/Rules/components/RuleEditor/RuleEditor.tsx +++ b/public/pages/Rules/components/RuleEditor/RuleEditor.tsx @@ -7,7 +7,7 @@ import React, { useState } from 'react'; import { ContentPanel } from '../../../../components/ContentPanel'; import { EuiSpacer, EuiButtonGroup } from '@elastic/eui'; import { Rule } from '../../../../../models/interfaces'; -import { RuleEditorFormState } from './RuleEditorFormState.model'; +import { RuleEditorFormState, ruleEditorStateDefaultValue } from './RuleEditorFormState.model'; import { mapFormToRule, mapRuleToForm } from './mappers'; import { VisualRuleEditor } from './VisualRuleEditor'; import { YamlRuleEditor } from './YamlRuleEditor'; @@ -24,21 +24,6 @@ export interface VisualEditorFormErrorsState { authorError: string | null; } -const newRuyleDefaultState: RuleEditorFormState = { - id: '25b9c01c-350d-4b95-bed1-836d04a4f324', - log_source: '', - logType: '', - name: '', - description: '', - status: '', - author: '', - references: [''], - tags: [], - detection: '', - level: '', - falsePositives: [''], -}; - const editorTypes = [ { id: 'visual', @@ -52,7 +37,9 @@ const editorTypes = [ export const RuleEditor: React.FC = ({ title, rule, FooterActions }) => { const [ruleEditorFormState, setRuleEditorFormState] = useState( - rule ? { ...mapRuleToForm(rule), id: newRuyleDefaultState.id } : newRuyleDefaultState + rule + ? { ...mapRuleToForm(rule), id: ruleEditorStateDefaultValue.id } + : ruleEditorStateDefaultValue ); const [selectedEditorType, setSelectedEditorType] = useState('visual'); diff --git a/public/pages/Rules/components/RuleEditor/RuleEditorFormState.model.ts b/public/pages/Rules/components/RuleEditor/RuleEditorFormState.model.ts index 91f0ed822..ccd8dd0c4 100644 --- a/public/pages/Rules/components/RuleEditor/RuleEditorFormState.model.ts +++ b/public/pages/Rules/components/RuleEditor/RuleEditorFormState.model.ts @@ -19,3 +19,18 @@ export interface RuleEditorFormState { level: string; falsePositives: string[]; } + +export const ruleEditorStateDefaultValue: RuleEditorFormState = { + id: '25b9c01c-350d-4b95-bed1-836d04a4f324', + log_source: '', + logType: '', + name: '', + description: '', + status: '', + author: '', + references: [''], + tags: [], + detection: '', + level: '', + falsePositives: [''], +}; diff --git a/public/pages/Rules/components/RuleEditor/YamlRuleEditor.tsx b/public/pages/Rules/components/RuleEditor/YamlRuleEditor.tsx index 07ddb2d27..645d09f98 100644 --- a/public/pages/Rules/components/RuleEditor/YamlRuleEditor.tsx +++ b/public/pages/Rules/components/RuleEditor/YamlRuleEditor.tsx @@ -20,10 +20,15 @@ export interface YamlEditorState { } const mapYamlObjectToYamlString = (rule: Rule): string => { - try { - const yamlString = dump(rule); + console.log('mapYamlObjectToYamlString', rule); - return yamlString; + try { + if (!rule.detection) { + const { detection, ...ruleWithoutDetection } = rule; + return dump(ruleWithoutDetection); + } else { + return dump(rule); + } } catch (error: any) { console.warn('Security Analytics - Rule Eritor - Yaml dump', error); return ''; @@ -31,6 +36,15 @@ const mapYamlObjectToYamlString = (rule: Rule): string => { }; const mapRuleToYamlObject = (rule: Rule): any => { + console.log('mapRuleToYamlObject', rule); + + let detection = undefined; + if (rule.detection) { + try { + detection = load(rule.detection); + } catch {} + } + const yamlObject: any = { id: rule.id, logsource: { product: rule.category }, @@ -42,26 +56,36 @@ const mapRuleToYamlObject = (rule: Rule): any => { status: rule.status, references: rule.references.map((reference) => reference.value), author: rule.author, - detection: load(rule.detection), + detection, }; return yamlObject; }; const mapYamlObjectToRule = (obj: any): Rule => { + let detection = ''; + if (obj.detection) { + try { + detection = dump(obj.detection); + } catch {} + } const rule: Rule = { id: obj.id, - category: obj.logsource.product, + category: obj.logsource ? obj.logsource.product : undefined, log_source: '', title: obj.title, description: obj.description, - tags: obj.tags.map((tag: string) => ({ value: tag })), - false_positives: obj.falsepositives.map((falsePositive: string) => ({ value: falsePositive })), + tags: obj.tags ? obj.tags.map((tag: string) => ({ value: tag })) : undefined, + false_positives: obj.falsepositives + ? obj.falsepositives.map((falsePositive: string) => ({ value: falsePositive })) + : undefined, level: obj.level, status: obj.status, - references: obj.references.map((reference: string) => ({ value: reference })), + references: obj.references + ? obj.references.map((reference: string) => ({ value: reference })) + : undefined, author: obj.author, - detection: dump(obj.detection), + detection, }; return rule; @@ -89,7 +113,6 @@ export const YamlRuleEditor: React.FC = ({ rule, change }) const rule = mapYamlObjectToRule(yamlObject); - console.log('onBlur rule load', yamlObject, rule); change(rule); setState((prevState) => ({ ...prevState, error: null })); } catch (error) { diff --git a/public/pages/Rules/components/RuleEditor/mappers.ts b/public/pages/Rules/components/RuleEditor/mappers.ts index 4a8240b4a..7da1b4db1 100644 --- a/public/pages/Rules/components/RuleEditor/mappers.ts +++ b/public/pages/Rules/components/RuleEditor/mappers.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ import { Rule } from '../../../../../models/interfaces'; -import { RuleEditorFormState } from './RuleEditorFormState.model'; +import { RuleEditorFormState, ruleEditorStateDefaultValue } from './RuleEditorFormState.model'; export const mapFormToRule = (formState: RuleEditorFormState): Rule => { return { @@ -33,10 +33,16 @@ export const mapRuleToForm = (rule: Rule): RuleEditorFormState => { description: rule.description, status: rule.status, author: rule.author, - references: rule.references.map((ref) => ref.value), - tags: rule.tags.map((tag) => ({ label: tag.value })), + references: rule.references + ? rule.references.map((ref) => ref.value) + : ruleEditorStateDefaultValue.references, + tags: rule.tags + ? rule.tags.map((tag) => ({ label: tag.value })) + : ruleEditorStateDefaultValue.tags, detection: rule.detection, level: rule.level, - falsePositives: rule.false_positives.map((falsePositive) => falsePositive.value), + falsePositives: rule.false_positives + ? rule.false_positives.map((falsePositive) => falsePositive.value) + : ruleEditorStateDefaultValue.falsePositives, }; };