From 49690fdf1d562f19080a3b588f1328b53e421855 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 9 Sep 2024 10:54:01 +0200 Subject: [PATCH 1/7] Add components for `name`, `description` and `tags` --- .../rule_details/rule_about_section.tsx | 2 +- .../final_readonly/field_readonly.tsx | 9 +++++ .../description/description.stories.tsx | 39 +++++++++++++++++++ .../fields/description/description.tsx | 36 +++++++++++++++++ .../fields/name/name.stories.tsx | 38 ++++++++++++++++++ .../final_readonly/fields/name/name.tsx | 36 +++++++++++++++++ .../fields/tags/tags.stories.tsx | 38 ++++++++++++++++++ .../final_readonly/fields/tags/tags.tsx | 29 ++++++++++++++ 8 files changed, 226 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_about_section.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_about_section.tsx index c7c9ec3ca732d..1d2e93df8e7f7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_about_section.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/rule_about_section.tsx @@ -256,7 +256,7 @@ interface TagsProps { tags: string[]; } -const Tags = ({ tags }: TagsProps) => ( +export const Tags = ({ tags }: TagsProps) => ( ); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx index f3d436ad7a26a..117c3e0991e4f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx @@ -21,6 +21,9 @@ import { ThreatReadOnly } from './fields/threat/threat'; import { ThreatIndexReadOnly } from './fields/threat_index/threat_index'; import { ThreatIndicatorPathReadOnly } from './fields/threat_indicator_path/threat_indicator_path'; import { ThreatQueryReadOnly } from './fields/threat_query/threat_query'; +import { NameReadOnly } from './fields/name/name'; +import { TagsReadOnly } from './fields/tags/tags'; +import { DescriptionReadOnly } from './fields/description/description'; interface FieldReadOnlyProps { fieldName: keyof DiffableAllFields; @@ -31,6 +34,8 @@ export function FieldReadOnly({ fieldName, finalDiffableRule }: FieldReadOnlyPro switch (fieldName) { case 'data_source': return ; + case 'description': + return ; case 'eql_query': return ( ); + case 'name': + return ; case 'related_integrations': return ( @@ -64,6 +71,8 @@ export function FieldReadOnly({ fieldName, finalDiffableRule }: FieldReadOnlyPro return ; case 'severity_mapping': return ; + case 'tags': + return ; case 'threat': return ; case 'threat_index': diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx new file mode 100644 index 0000000000000..8eb713c812757 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { Story } from '@storybook/react'; +import { DescriptionReadOnly } from './description'; +import { FieldReadOnly } from '../../field_readonly'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; + +export default { + component: DescriptionReadOnly, + title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/description', +}; + +interface TemplateProps { + finalDiffableRule: Partial; +} + +const Template: Story = (args) => { + return ( + + ); +}; + +export const Default = Template.bind({}); + +Default.args = { + finalDiffableRule: { + description: + "Identifies the occurrence of a security alert from the Google Workspace alerts center. Google Workspace's security alert center provides an overview of actionable alerts that may be affecting an organization's domain. An alert is a warning of a potential security issue that Google has detected.", + }, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx new file mode 100644 index 0000000000000..34ff5b3013b1d --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiDescriptionList } from '@elastic/eui'; +import * as ruleDetailsI18n from '../../../../translations'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; + +interface RuleDescriptionProps { + description: DiffableAllFields['name']; +} + +function RuleDescription({ description }: RuleDescriptionProps) { + return <>{description}; +} + +interface DescriptionReadOnlyProps { + description: DiffableAllFields['description']; +} + +export function DescriptionReadOnly({ description }: DescriptionReadOnlyProps) { + return ( + , + }, + ]} + /> + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx new file mode 100644 index 0000000000000..cf0983cd9b6b6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { Story } from '@storybook/react'; +import { NameReadOnly } from './name'; +import { FieldReadOnly } from '../../field_readonly'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; + +export default { + component: NameReadOnly, + title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/name', +}; + +interface TemplateProps { + finalDiffableRule: Partial; +} + +const Template: Story = (args) => { + return ( + + ); +}; + +export const Default = Template.bind({}); + +Default.args = { + finalDiffableRule: { + name: 'Forwarded Google Workspace Security Alert', + }, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx new file mode 100644 index 0000000000000..65743470629ea --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiDescriptionList } from '@elastic/eui'; +import * as ruleDetailsI18n from '../../../../translations'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; + +interface RuleNameProps { + name: DiffableAllFields['name']; +} + +function RuleName({ name }: RuleNameProps) { + return <>{name}; +} + +interface NameReadOnlyProps { + name: DiffableAllFields['name']; +} + +export function NameReadOnly({ name }: NameReadOnlyProps) { + return ( + , + }, + ]} + /> + ); +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx new file mode 100644 index 0000000000000..19160cca2794e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { Story } from '@storybook/react'; +import { TagsReadOnly } from './tags'; +import { FieldReadOnly } from '../../field_readonly'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; + +export default { + component: TagsReadOnly, + title: 'Rule Management/Prebuilt Rules/Upgrade Flyout/ThreeWayDiff/FieldReadOnly/tags', +}; + +interface TemplateProps { + finalDiffableRule: Partial; +} + +const Template: Story = (args) => { + return ( + + ); +}; + +export const Default = Template.bind({}); + +Default.args = { + finalDiffableRule: { + tags: ['Elastic', 'Cloud', 'Google Workspace', 'Log Auditing', 'Threat Detection'], + }, +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx new file mode 100644 index 0000000000000..31ef04d6309fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiDescriptionList } from '@elastic/eui'; +import * as ruleDetailsI18n from '../../../../translations'; +import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import { Tags } from '../../../../rule_about_section'; + +interface TagsReadOnlyProps { + tags: DiffableAllFields['tags']; +} + +export function TagsReadOnly({ tags }: TagsReadOnlyProps) { + return ( + , + }, + ]} + /> + ); +} From 040b61a163d3d3e0d8697704f6b2d9a07fcf259f Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Mon, 16 Sep 2024 17:08:45 +0200 Subject: [PATCH 2/7] Update comments related to ThreeWayDiff --- .../model/diff/three_way_diff/three_way_diff.ts | 1 + .../model/diff/three_way_diff/three_way_diff_conflict.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts index 7b71bb6f16c7a..c8c4238709849 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff.ts @@ -131,6 +131,7 @@ export interface ThreeWayDiff { * True if: * - base=A, current=A, target=B * - base=A, current=B, target=C + * - base=, current=A, target=B */ has_update: boolean; diff --git a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_conflict.ts b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_conflict.ts index f33c52d33abfc..541c51d4f571f 100644 --- a/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_conflict.ts +++ b/x-pack/plugins/security_solution/common/api/detection_engine/prebuilt_rules/model/diff/three_way_diff/three_way_diff_conflict.ts @@ -7,8 +7,8 @@ /** * Enum of possible conflict outcomes of a three-way diff: - * - NON_SOLVABLE_CONFLICT: current != target and we couldn't automatically resolve the conflict between them - * - SOLVABLE_CONFLICT: current != target and we automatically resolved the conflict between them + * - NON_SOLVABLE: current != target and we couldn't automatically resolve the conflict between them + * - SOLVABLE: current != target and we automatically resolved the conflict between them * - NO_CONFLICT: * - current == target (value won't change) * - current != target && current == base (stock rule will get a new value) From a97131577568f06a3fb33053a74adf4738d8db51 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 17 Sep 2024 16:16:02 +0200 Subject: [PATCH 3/7] Move from using `DiffableAllFields` to `DiffableRule` type in Storybooks --- .../common_rule_field_readonly.tsx | 91 ++++++++++ .../custom_query_rule_field_readonly.tsx | 39 ++++ .../eql_rule_field_readonly.tsx | 35 ++++ .../esql_rule_field_readonly.tsx | 30 ++++ .../final_readonly/field_readonly.tsx | 143 ++++++++------- .../data_source/data_source.stories.tsx | 18 +- .../description/description.stories.tsx | 16 +- .../fields/eql_query/eql_query.stories.tsx | 18 +- .../fields/esql_query/esql_query.stories.tsx | 16 +- .../fields/kql_query/kql_query.stories.tsx | 34 ++-- .../machine_learning_job_id.stories.tsx | 11 +- .../fields/name/name.stories.tsx | 16 +- .../related_integrations.stories.tsx | 11 +- .../required_fields.stories.tsx | 16 +- .../risk_score_mapping.stories.tsx | 14 +- .../severity_mapping.stories.tsx | 16 +- .../fields/tags/tags.stories.tsx | 16 +- .../fields/threat/threat.stories.tsx | 16 +- .../threat_index/threat_index.stories.tsx | 16 +- .../threat_indicator_path.stories.tsx | 14 +- .../threat_mapping/threat_mapping.stories.tsx | 16 +- .../threat_query/threat_query.stories.tsx | 18 +- .../machine_learning_rule_field_readonly.tsx | 34 ++++ .../new_terms_rule_field_readonly.tsx | 39 ++++ .../saved_query_rule_field_readonly.tsx | 39 ++++ .../final_readonly/storybook/mocks.ts | 168 ++++++++++++++++++ .../threat_match_rule_field_readonly.tsx | 60 +++++++ .../threshold_rule_field_readonly.tsx | 39 ++++ 28 files changed, 768 insertions(+), 231 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx create mode 100644 x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx new file mode 100644 index 0000000000000..35bde351bbeb6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/common_rule_field_readonly.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { + DiffableCommonFields, + DiffableRule, +} from '../../../../../../../common/api/detection_engine'; +import { RelatedIntegrationsReadOnly } from './fields/related_integrations/related_integrations'; +import { RequiredFieldsReadOnly } from './fields/required_fields/required_fields'; +import { SeverityMappingReadOnly } from './fields/severity_mapping/severity_mapping'; +import { RiskScoreMappingReadOnly } from './fields/risk_score_mapping/risk_score_mapping'; +import { ThreatReadOnly } from './fields/threat/threat'; +import { NameReadOnly } from './fields/name/name'; +import { TagsReadOnly } from './fields/tags/tags'; +import { DescriptionReadOnly } from './fields/description/description'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface CommonRuleFieldReadOnlyProps { + fieldName: keyof DiffableCommonFields; + finalDiffableRule: DiffableRule; +} + +// eslint-disable-next-line complexity +export function CommonRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: CommonRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'author': + return null; + case 'building_block': + return null; + case 'description': + return ; + case 'exceptions_list': + return null; + case 'investigation_fields': + return null; + case 'false_positives': + return null; + case 'license': + return null; + case 'max_signals': + return null; + case 'name': + return ; + case 'note': + return null; + case 'related_integrations': + return ( + + ); + case 'required_fields': + return ; + case 'risk_score_mapping': + return ; + case 'rule_schedule': + return null; + case 'severity_mapping': + return ; + case 'tags': + return ; + case 'threat': + return ; + case 'references': + return null; + case 'risk_score': + return null; + case 'rule_id': + return null; + case 'rule_name_override': + return null; + case 'setup': + return null; + case 'severity': + return null; + case 'timestamp_override': + return null; + case 'timeline_template': + return null; + case 'version': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx new file mode 100644 index 0000000000000..b58e7328dc703 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableCustomQueryFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { KqlQueryReadOnly } from './fields/kql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface CustomQueryRuleFieldReadOnlyProps { + fieldName: keyof DiffableCustomQueryFields; + finalDiffableRule: DiffableCustomQueryFields; +} + +export function CustomQueryRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: CustomQueryRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'kql_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx new file mode 100644 index 0000000000000..e2c79244543ad --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableEqlFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { EqlQueryReadOnly } from './fields/eql_query/eql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface EqlRuleFieldReadOnlyProps { + fieldName: keyof DiffableEqlFields; + finalDiffableRule: DiffableEqlFields; +} + +export function EqlRuleFieldReadOnly({ fieldName, finalDiffableRule }: EqlRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'eql_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx new file mode 100644 index 0000000000000..c9e5cf9298e0b --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx @@ -0,0 +1,30 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableEsqlFields } from '../../../../../../../common/api/detection_engine'; +import { EsqlQueryReadOnly } from './fields/esql_query/esql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface EsqlRuleFieldReadOnlyProps { + fieldName: keyof DiffableEsqlFields; + finalDiffableRule: DiffableEsqlFields; +} + +export function EsqlRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: EsqlRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'esql_query': + return ; + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx index 117c3e0991e4f..d8d31e343278b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/field_readonly.tsx @@ -5,94 +5,105 @@ * 2.0. */ -import React from 'react'; -import type { DiffableAllFields } from '../../../../../../../common/api/detection_engine'; -import { KqlQueryReadOnly } from './fields/kql_query'; -import { DataSourceReadOnly } from './fields/data_source/data_source'; -import { EqlQueryReadOnly } from './fields/eql_query/eql_query'; -import { EsqlQueryReadOnly } from './fields/esql_query/esql_query'; -import { MachineLearningJobIdReadOnly } from './fields/machine_learning_job_id/machine_learning_job_id'; -import { RelatedIntegrationsReadOnly } from './fields/related_integrations/related_integrations'; -import { RequiredFieldsReadOnly } from './fields/required_fields/required_fields'; -import { SeverityMappingReadOnly } from './fields/severity_mapping/severity_mapping'; -import { RiskScoreMappingReadOnly } from './fields/risk_score_mapping/risk_score_mapping'; -import { ThreatMappingReadOnly } from './fields/threat_mapping/threat_mapping'; -import { ThreatReadOnly } from './fields/threat/threat'; -import { ThreatIndexReadOnly } from './fields/threat_index/threat_index'; -import { ThreatIndicatorPathReadOnly } from './fields/threat_indicator_path/threat_indicator_path'; -import { ThreatQueryReadOnly } from './fields/threat_query/threat_query'; -import { NameReadOnly } from './fields/name/name'; -import { TagsReadOnly } from './fields/tags/tags'; -import { DescriptionReadOnly } from './fields/description/description'; +import React, { useMemo } from 'react'; +import { DiffableCommonFields } from '../../../../../../../common/api/detection_engine'; +import type { + DiffableRule, + DiffableCustomQueryFields, + DiffableSavedQueryFields, + DiffableEqlFields, + DiffableThreatMatchFields, + DiffableThresholdFields, + DiffableNewTermsFields, + DiffableEsqlFields, + DiffableMachineLearningFields, +} from '../../../../../../../common/api/detection_engine'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; +import { CustomQueryRuleFieldReadOnly } from './custom_query_rule_field_readonly'; +import { SavedQueryRuleFieldReadOnly } from './saved_query_rule_field_readonly'; +import { EqlRuleFieldReadOnly } from './eql_rule_field_readonly'; +import { EsqlRuleFieldReadOnly } from './esql_rule_field_readonly'; +import { ThreatMatchRuleFieldReadOnly } from './threat_match_rule_field_readonly'; +import { ThresholdRuleFieldReadOnly } from './threshold_rule_field_readonly'; +import { MachineLearningRuleFieldReadOnly } from './machine_learning_rule_field_readonly'; +import { NewTermsRuleFieldReadOnly } from './new_terms_rule_field_readonly'; +import { CommonRuleFieldReadOnly } from './common_rule_field_readonly'; interface FieldReadOnlyProps { - fieldName: keyof DiffableAllFields; - finalDiffableRule: DiffableAllFields; + fieldName: string; + finalDiffableRule: DiffableRule; } export function FieldReadOnly({ fieldName, finalDiffableRule }: FieldReadOnlyProps) { - switch (fieldName) { - case 'data_source': - return ; - case 'description': - return ; - case 'eql_query': + const { data: commonField } = useMemo( + () => DiffableCommonFields.keyof().safeParse(fieldName), + [fieldName] + ); + + if (commonField) { + return ( + + ); + } + + switch (finalDiffableRule.type) { + case 'query': + return ( + + ); + case 'saved_query': return ( - ); - case 'esql_query': - return ; - case 'kql_query': + case 'eql': return ( - ); - case 'machine_learning_job_id': + case 'esql': return ( - ); - case 'name': - return ; - case 'related_integrations': + case 'threat_match': return ( - + + ); + case 'threshold': + return ( + ); - case 'required_fields': - return ; - case 'risk_score_mapping': - return ; - case 'severity_mapping': - return ; - case 'tags': - return ; - case 'threat': - return ; - case 'threat_index': - return ; - case 'threat_indicator_path': + case 'machine_learning': return ( - ); - case 'threat_mapping': - return ; - case 'threat_query': + case 'new_terms': return ( - ); default: - return null; + return assertUnreachable(finalDiffableRule); } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx index 6ffe47a254de9..9deebf794c241 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.stories.tsx @@ -8,12 +8,13 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { dataSourceWithDataView, dataSourceWithIndexPatterns, mockDataView, + mockCustomQueryRule, } from '../../storybook/mocks'; export default { @@ -22,17 +23,14 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; kibanaServicesMock?: Record; } const Template: Story = (args) => { return ( - + ); }; @@ -40,17 +38,17 @@ const Template: Story = (args) => { export const DataSourceWithIndexPatterns = Template.bind({}); DataSourceWithIndexPatterns.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ data_source: dataSourceWithIndexPatterns, - }, + }), }; export const DataSourceWithDataView = Template.bind({}); DataSourceWithDataView.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ data_source: dataSourceWithDataView, - }, + }), kibanaServicesMock: { data: { dataViews: { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx index 8eb713c812757..ba094ecfe54f9 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.stories.tsx @@ -9,7 +9,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { DescriptionReadOnly } from './description'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: DescriptionReadOnly, @@ -17,23 +18,18 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ description: "Identifies the occurrence of a security alert from the Google Workspace alerts center. Google Workspace's security alert center provides an overview of actionable alerts that may be affecting an organization's domain. An alert is a warning of a potential security issue that Google has detected.", - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx index 205e87e209068..af835c5a92779 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.stories.tsx @@ -8,7 +8,7 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { EqlQueryReadOnly } from './eql_query'; import { @@ -16,6 +16,7 @@ import { dataSourceWithIndexPatterns, eqlQuery, mockDataView, + mockEqlRule, } from '../../storybook/mocks'; export default { @@ -24,17 +25,14 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; kibanaServicesMock?: Record; } const Template: Story = (args) => { return ( - + ); }; @@ -42,10 +40,10 @@ const Template: Story = (args) => { export const EqlQueryWithIndexPatterns = Template.bind({}); EqlQueryWithIndexPatterns.args = { - finalDiffableRule: { + finalDiffableRule: mockEqlRule({ eql_query: eqlQuery, data_source: dataSourceWithIndexPatterns, - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -58,10 +56,10 @@ EqlQueryWithIndexPatterns.args = { export const EqlQueryWithDataView = Template.bind({}); EqlQueryWithDataView.args = { - finalDiffableRule: { + finalDiffableRule: mockEqlRule({ eql_query: eqlQuery, data_source: dataSourceWithDataView, - }, + }), kibanaServicesMock: { data: { dataViews: { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx index cda1c99a218bb..664294dbe768c 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.stories.tsx @@ -8,7 +8,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockEsqlRule } from '../../storybook/mocks'; export default { component: FieldReadOnly, @@ -16,25 +17,20 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockEsqlRule({ esql_query: { query: `SELECT user.name, source.ip FROM "logs-*" WHERE event.action = 'user_login' AND event.outcome = 'failure'`, language: 'esql', }, - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx index 61d31d983b183..2b4844ceac5d5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/kql_query.stories.tsx @@ -8,18 +8,17 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { - DiffableAllFields, - RuleKqlQuery, -} from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { dataSourceWithDataView, dataSourceWithIndexPatterns, inlineKqlQuery, mockDataView, + mockCustomQueryRule, savedKqlQuery, savedQueryResponse, + mockSavedQueryRule, } from '../../storybook/mocks'; export default { @@ -28,17 +27,14 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial | { kql_query: RuleKqlQuery }; + finalDiffableRule: DiffableRule; kibanaServicesMock?: Record; } const Template: Story = (args) => { return ( - + ); }; @@ -46,10 +42,10 @@ const Template: Story = (args) => { export const InlineKqlQueryWithIndexPatterns = Template.bind({}); InlineKqlQueryWithIndexPatterns.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ kql_query: inlineKqlQuery, data_source: dataSourceWithIndexPatterns, - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -62,10 +58,10 @@ InlineKqlQueryWithIndexPatterns.args = { export const InlineKqlQueryWithDataView = Template.bind({}); InlineKqlQueryWithDataView.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ kql_query: inlineKqlQuery, data_source: dataSourceWithDataView, - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -82,9 +78,9 @@ export const InlineKqlQueryWithoutDataSource = Template.bind({}); Component would fall back to the default index pattern in such case. */ InlineKqlQueryWithoutDataSource.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ kql_query: inlineKqlQuery, - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -97,11 +93,11 @@ InlineKqlQueryWithoutDataSource.args = { export const SavedKqlQueryWithIndexPatterns = Template.bind({}); SavedKqlQueryWithIndexPatterns.args = { - finalDiffableRule: { + finalDiffableRule: mockSavedQueryRule({ kql_query: savedKqlQuery, data_source: dataSourceWithIndexPatterns, type: 'saved_query', - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -117,11 +113,11 @@ SavedKqlQueryWithIndexPatterns.args = { export const SavedKqlQueryWithDataView = Template.bind({}); SavedKqlQueryWithDataView.args = { - finalDiffableRule: { + finalDiffableRule: mockSavedQueryRule({ kql_query: savedKqlQuery, data_source: dataSourceWithDataView, type: 'saved_query', - }, + }), kibanaServicesMock: { data: { dataViews: { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx index 4d334f3aa57ec..8dc504b737e00 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.stories.tsx @@ -9,12 +9,13 @@ import React from 'react'; import { useQueryClient } from '@tanstack/react-query'; import type { Story } from '@storybook/react'; import { MachineLearningJobIdReadOnly } from './machine_learning_job_id'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { FieldReadOnly } from '../../field_readonly'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { GET_MODULES_QUERY_KEY } from '../../../../../../../../common/components/ml_popover/hooks/use_fetch_modules_query'; import { GET_RECOGNIZER_QUERY_KEY } from '../../../../../../../../common/components/ml_popover/hooks/use_fetch_recognizer_query'; import { GET_JOBS_SUMMARY_QUERY_KEY } from '../../../../../../../../common/components/ml/hooks/use_fetch_jobs_summary_query'; +import { mockMachineLearningRule } from '../../storybook/mocks'; export default { component: MachineLearningJobIdReadOnly, @@ -58,7 +59,7 @@ function MockMlData({ children }: { children: React.ReactNode }) { } interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { @@ -67,7 +68,7 @@ const Template: Story = (args) => { @@ -77,7 +78,7 @@ const Template: Story = (args) => { export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockMachineLearningRule({ machine_learning_job_id: 'auth_high_count_logon_events', - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx index cf0983cd9b6b6..1451d3b70ef8b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.stories.tsx @@ -9,7 +9,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { NameReadOnly } from './name'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: NameReadOnly, @@ -17,22 +18,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ name: 'Forwarded Google Workspace Security Alert', - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx index 9855e2f974096..4657b21b0c64e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/related_integrations/related_integrations.stories.tsx @@ -11,7 +11,8 @@ import type { Story } from '@storybook/react'; import { RelatedIntegrationsReadOnly } from './related_integrations'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: RelatedIntegrationsReadOnly, @@ -39,7 +40,7 @@ function MockRelatedIntegrationsData({ children }: { children: React.ReactNode } } interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { @@ -48,7 +49,7 @@ const Template: Story = (args) => { @@ -58,7 +59,7 @@ const Template: Story = (args) => { export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ related_integrations: [{ package: 'endpoint', version: '^8.2.0' }], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx index 2957d8ff7ceaf..44d3383ae8227 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/required_fields/required_fields.stories.tsx @@ -8,7 +8,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { RequiredFieldsReadOnly } from './required_fields'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: RequiredFieldsReadOnly, @@ -16,25 +17,20 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ required_fields: [ { name: 'event.kind', type: 'keyword', ecs: true }, { name: 'event.module', type: 'keyword', ecs: true }, ], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx index 76775d6da4586..40c8644ffd3ea 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/risk_score_mapping/risk_score_mapping.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { RiskScoreMappingReadOnly } from './risk_score_mapping'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: RiskScoreMappingReadOnly, @@ -18,22 +19,19 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { return ( - + ); }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ risk_score_mapping: [{ field: 'event.risk_score', operator: 'equals', value: '' }], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx index 92d7b95b17c2b..6a4b365a86db5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/severity_mapping/severity_mapping.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { SeverityMappingReadOnly } from './severity_mapping'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: SeverityMappingReadOnly, @@ -18,22 +19,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ severity_mapping: [ { field: 'event.severity', @@ -48,5 +44,5 @@ Default.args = { value: 'VERY HIGH', }, ], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx index 19160cca2794e..b2c483cbc8c97 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.stories.tsx @@ -9,7 +9,8 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { TagsReadOnly } from './tags'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: TagsReadOnly, @@ -17,22 +18,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ tags: ['Elastic', 'Cloud', 'Google Workspace', 'Log Auditing', 'Threat Detection'], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx index 4909174dcb577..aa95633349260 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat/threat.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatReadOnly } from './threat'; +import { mockCustomQueryRule } from '../../storybook/mocks'; export default { component: ThreatReadOnly, @@ -17,22 +18,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockCustomQueryRule({ threat: [ { framework: 'MITRE ATT&CK', @@ -57,5 +53,5 @@ Default.args = { ], }, ], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx index c42fa2e890c52..4f10cb8932ab1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_index/threat_index.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndexReadOnly } from './threat_index'; +import { mockThreatMatchRule } from '../../storybook/mocks'; export default { component: ThreatIndexReadOnly, @@ -17,22 +18,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockThreatMatchRule({ threat_index: ['logs-ti_*', 'logs-defend_*'], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx index 34f0cdbcac317..be8906d76eb6b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_indicator_path/threat_indicator_path.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatIndicatorPathReadOnly } from './threat_indicator_path'; +import { mockThreatMatchRule } from '../../storybook/mocks'; export default { component: ThreatIndicatorPathReadOnly, @@ -18,22 +19,19 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { return ( - + ); }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockThreatMatchRule({ threat_indicator_path: 'threat.indicator', - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx index 05d1aaa6cb028..4f5b8f608c4bf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_mapping/threat_mapping.stories.tsx @@ -8,8 +8,9 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatMappingReadOnly } from './threat_mapping'; +import { mockThreatMatchRule } from '../../storybook/mocks'; export default { component: ThreatMappingReadOnly, @@ -17,22 +18,17 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; } const Template: Story = (args) => { - return ( - - ); + return ; }; export const Default = Template.bind({}); Default.args = { - finalDiffableRule: { + finalDiffableRule: mockThreatMatchRule({ threat_mapping: [ { entries: [ @@ -44,5 +40,5 @@ Default.args = { ], }, ], - }, + }), }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx index 5b59287255bc9..28b4cd65ba78b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.stories.tsx @@ -8,13 +8,14 @@ import React from 'react'; import type { Story } from '@storybook/react'; import { FieldReadOnly } from '../../field_readonly'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { DiffableRule } from '../../../../../../../../../common/api/detection_engine'; import { ThreatQueryReadOnly } from './threat_query'; import { dataSourceWithDataView, dataSourceWithIndexPatterns, inlineKqlQuery, mockDataView, + mockThreatMatchRule, } from '../../storybook/mocks'; import { ThreeWayDiffStorybookProviders } from '../../storybook/three_way_diff_storybook_providers'; @@ -24,17 +25,14 @@ export default { }; interface TemplateProps { - finalDiffableRule: Partial; + finalDiffableRule: DiffableRule; kibanaServicesMock?: Record; } const Template: Story = (args) => { return ( - + ); }; @@ -42,10 +40,10 @@ const Template: Story = (args) => { export const ThreatQueryWithIndexPatterns = Template.bind({}); ThreatQueryWithIndexPatterns.args = { - finalDiffableRule: { + finalDiffableRule: mockThreatMatchRule({ threat_query: inlineKqlQuery, data_source: dataSourceWithIndexPatterns, - }, + }), kibanaServicesMock: { data: { dataViews: { @@ -58,10 +56,10 @@ ThreatQueryWithIndexPatterns.args = { export const ThreatQueryWithDataView = Template.bind({}); ThreatQueryWithDataView.args = { - finalDiffableRule: { + finalDiffableRule: mockThreatMatchRule({ threat_query: inlineKqlQuery, data_source: dataSourceWithDataView, - }, + }), kibanaServicesMock: { data: { dataViews: { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx new file mode 100644 index 0000000000000..2f3358e9cebaf --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableMachineLearningFields } from '../../../../../../../common/api/detection_engine'; +import { MachineLearningJobIdReadOnly } from './fields/machine_learning_job_id/machine_learning_job_id'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface MachineLearningRuleFieldReadOnlyProps { + fieldName: keyof DiffableMachineLearningFields; + finalDiffableRule: DiffableMachineLearningFields; +} + +export function MachineLearningRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: MachineLearningRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'machine_learning_job_id': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx new file mode 100644 index 0000000000000..c4a77fbeece99 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableNewTermsFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { KqlQueryReadOnly } from './fields/kql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface NewTermsRuleFieldReadOnlyProps { + fieldName: keyof DiffableNewTermsFields; + finalDiffableRule: DiffableNewTermsFields; +} + +export function NewTermsRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: NewTermsRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'kql_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx new file mode 100644 index 0000000000000..9c58d4907fa8c --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableSavedQueryFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { KqlQueryReadOnly } from './fields/kql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface SavedQueryRuleFieldReadOnlyProps { + fieldName: keyof DiffableSavedQueryFields; + finalDiffableRule: DiffableSavedQueryFields; +} + +export function SavedQueryRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: SavedQueryRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'kql_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts index 2b21558e9b0ca..2565ddbd04bf3 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts @@ -10,8 +10,17 @@ import { DataView } from '@kbn/data-views-plugin/common'; import { DataSourceType, KqlQueryType } from '../../../../../../../../common/api/detection_engine'; import type { DiffableAllFields, + DiffableCommonFields, + DiffableCustomQueryFields, + DiffableEqlFields, + DiffableEsqlFields, + DiffableMachineLearningFields, + DiffableRule, + DiffableSavedQueryFields, + DiffableThreatMatchFields, SavedKqlQuery, } from '../../../../../../../../common/api/detection_engine'; +import { DEFAULT_MAX_SIGNALS } from '../../../../../../../../common/constants'; export const filters = [ { @@ -103,3 +112,162 @@ export function mockDataView(spec: Partial = {}): DataView return dataView; } + +const commonDiffableRuleFields: DiffableCommonFields = { + rule_id: 'some-rule-id', + version: 1, + + name: 'Some Rule Name', + tags: [], + description: 'Some rule description', + severity: 'low', + severity_mapping: [], + risk_score: 1, + risk_score_mapping: [], + + references: [], + false_positives: [], + threat: [], + note: '', + setup: '', + related_integrations: [], + required_fields: [], + author: [], + license: '', + + rule_schedule: { + interval: '5m', + lookback: '360s', + }, + exceptions_list: [], + max_signals: DEFAULT_MAX_SIGNALS, +}; + +const customQueryDiffableRuleFields: DiffableCustomQueryFields = { + type: 'query', + kql_query: { + type: KqlQueryType.inline_query, + query: '*', + language: 'kuery', + filters: [], + }, +}; + +export function mockCustomQueryRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...customQueryDiffableRuleFields, + ...overrides, + }; +} + +const savedQueryDiffableRuleFields: DiffableSavedQueryFields = { + type: 'saved_query', + kql_query: { + type: KqlQueryType.saved_query, + saved_query_id: 'some-saved-query-id', + }, +}; + +export function mockSavedQueryRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...savedQueryDiffableRuleFields, + ...overrides, + }; +} + +const eqlDiffableRuleFields: DiffableEqlFields = { + type: 'eql', + eql_query: { + query: 'any where true', + language: 'eql', + filters: [], + }, +}; + +export function mockEqlRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...eqlDiffableRuleFields, + ...overrides, + }; +} + +const esqlDiffableRuleFields: DiffableEsqlFields = { + type: 'esql', + esql_query: { + query: 'SELECT * FROM any', + language: 'esql', + }, +}; + +export function mockEsqlRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...esqlDiffableRuleFields, + ...overrides, + }; +} + +const machineLearningDiffableRuleFields: DiffableMachineLearningFields = { + type: 'machine_learning', + machine_learning_job_id: 'ml-job-id-123', + anomaly_threshold: 0, +}; + +export function mockMachineLearningRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...machineLearningDiffableRuleFields, + ...overrides, + }; +} + +const threatMatchDiffableRuleFields: DiffableThreatMatchFields = { + type: 'threat_match', + kql_query: { + type: KqlQueryType.inline_query, + query: '*', + language: 'kuery', + filters: [], + }, + threat_query: { + type: KqlQueryType.inline_query, + query: '*', + language: 'kuery', + filters: [], + }, + threat_index: [], + threat_mapping: [ + { + entries: [ + { + field: 'abc', + type: 'mapping', + value: 'xyz', + }, + ], + }, + ], +}; + +export function mockThreatMatchRule( + overrides: Partial +): DiffableRule { + return { + ...commonDiffableRuleFields, + ...threatMatchDiffableRuleFields, + ...overrides, + }; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx new file mode 100644 index 0000000000000..0e1e4c34377fc --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableThreatMatchFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { KqlQueryReadOnly } from './fields/kql_query'; +import { ThreatIndexReadOnly } from './fields/threat_index/threat_index'; +import { ThreatIndicatorPathReadOnly } from './fields/threat_indicator_path/threat_indicator_path'; +import { ThreatMappingReadOnly } from './fields/threat_mapping/threat_mapping'; +import { ThreatQueryReadOnly } from './fields/threat_query/threat_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface ThreatMatchRuleFieldReadOnlyProps { + fieldName: keyof DiffableThreatMatchFields; + finalDiffableRule: DiffableThreatMatchFields; +} + +export function ThreatMatchRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: ThreatMatchRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'kql_query': + return ( + + ); + case 'threat_index': + return ; + case 'threat_indicator_path': + return ( + + ); + case 'threat_mapping': + return ; + case 'threat_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx new file mode 100644 index 0000000000000..7d632b7754987 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import type { DiffableThresholdFields } from '../../../../../../../common/api/detection_engine'; +import { DataSourceReadOnly } from './fields/data_source/data_source'; +import { KqlQueryReadOnly } from './fields/kql_query'; +import { assertUnreachable } from '../../../../../../../common/utility_types'; + +interface ThresholdRuleFieldReadOnlyProps { + fieldName: keyof DiffableThresholdFields; + finalDiffableRule: DiffableThresholdFields; +} + +export function ThresholdRuleFieldReadOnly({ + fieldName, + finalDiffableRule, +}: ThresholdRuleFieldReadOnlyProps) { + switch (fieldName) { + case 'data_source': + return ; + case 'kql_query': + return ( + + ); + case 'type': + return null; + default: + return assertUnreachable(fieldName); + } +} From 6f9344e1e45f9c4443dbe46e166b6bd4c13faac4 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Tue, 17 Sep 2024 17:51:09 +0200 Subject: [PATCH 4/7] Temporarily remove `assertUnreachable` checks to make TS happy --- .../final_readonly/custom_query_rule_field_readonly.tsx | 5 +---- .../final_readonly/eql_rule_field_readonly.tsx | 3 +-- .../final_readonly/esql_rule_field_readonly.tsx | 3 +-- .../final_readonly/machine_learning_rule_field_readonly.tsx | 3 +-- .../final_readonly/new_terms_rule_field_readonly.tsx | 3 +-- .../final_readonly/saved_query_rule_field_readonly.tsx | 3 +-- .../final_readonly/threat_match_rule_field_readonly.tsx | 3 +-- .../final_readonly/threshold_rule_field_readonly.tsx | 3 +-- 8 files changed, 8 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx index b58e7328dc703..3d22d268438c4 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/custom_query_rule_field_readonly.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { DiffableCustomQueryFields } from '../../../../../../../common/api/detection_engine'; import { DataSourceReadOnly } from './fields/data_source/data_source'; import { KqlQueryReadOnly } from './fields/kql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface CustomQueryRuleFieldReadOnlyProps { fieldName: keyof DiffableCustomQueryFields; @@ -31,9 +30,7 @@ export function CustomQueryRuleFieldReadOnly({ ruleType={finalDiffableRule.type} /> ); - case 'type': - return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx index e2c79244543ad..126775965724b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/eql_rule_field_readonly.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { DiffableEqlFields } from '../../../../../../../common/api/detection_engine'; import { DataSourceReadOnly } from './fields/data_source/data_source'; import { EqlQueryReadOnly } from './fields/eql_query/eql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface EqlRuleFieldReadOnlyProps { fieldName: keyof DiffableEqlFields; @@ -30,6 +29,6 @@ export function EqlRuleFieldReadOnly({ fieldName, finalDiffableRule }: EqlRuleFi case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx index c9e5cf9298e0b..755ad6b1b4789 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/esql_rule_field_readonly.tsx @@ -8,7 +8,6 @@ import React from 'react'; import type { DiffableEsqlFields } from '../../../../../../../common/api/detection_engine'; import { EsqlQueryReadOnly } from './fields/esql_query/esql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface EsqlRuleFieldReadOnlyProps { fieldName: keyof DiffableEsqlFields; @@ -25,6 +24,6 @@ export function EsqlRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx index 2f3358e9cebaf..5ebc6f80b13f2 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/machine_learning_rule_field_readonly.tsx @@ -8,7 +8,6 @@ import React from 'react'; import type { DiffableMachineLearningFields } from '../../../../../../../common/api/detection_engine'; import { MachineLearningJobIdReadOnly } from './fields/machine_learning_job_id/machine_learning_job_id'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface MachineLearningRuleFieldReadOnlyProps { fieldName: keyof DiffableMachineLearningFields; @@ -29,6 +28,6 @@ export function MachineLearningRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx index c4a77fbeece99..0e2b52c71ba2b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/new_terms_rule_field_readonly.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { DiffableNewTermsFields } from '../../../../../../../common/api/detection_engine'; import { DataSourceReadOnly } from './fields/data_source/data_source'; import { KqlQueryReadOnly } from './fields/kql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface NewTermsRuleFieldReadOnlyProps { fieldName: keyof DiffableNewTermsFields; @@ -34,6 +33,6 @@ export function NewTermsRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx index 9c58d4907fa8c..41e2e0c32108b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/saved_query_rule_field_readonly.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { DiffableSavedQueryFields } from '../../../../../../../common/api/detection_engine'; import { DataSourceReadOnly } from './fields/data_source/data_source'; import { KqlQueryReadOnly } from './fields/kql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface SavedQueryRuleFieldReadOnlyProps { fieldName: keyof DiffableSavedQueryFields; @@ -34,6 +33,6 @@ export function SavedQueryRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx index 0e1e4c34377fc..11fd941601922 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threat_match_rule_field_readonly.tsx @@ -13,7 +13,6 @@ import { ThreatIndexReadOnly } from './fields/threat_index/threat_index'; import { ThreatIndicatorPathReadOnly } from './fields/threat_indicator_path/threat_indicator_path'; import { ThreatMappingReadOnly } from './fields/threat_mapping/threat_mapping'; import { ThreatQueryReadOnly } from './fields/threat_query/threat_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface ThreatMatchRuleFieldReadOnlyProps { fieldName: keyof DiffableThreatMatchFields; @@ -55,6 +54,6 @@ export function ThreatMatchRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx index 7d632b7754987..da7d3984d7ccb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/threshold_rule_field_readonly.tsx @@ -9,7 +9,6 @@ import React from 'react'; import type { DiffableThresholdFields } from '../../../../../../../common/api/detection_engine'; import { DataSourceReadOnly } from './fields/data_source/data_source'; import { KqlQueryReadOnly } from './fields/kql_query'; -import { assertUnreachable } from '../../../../../../../common/utility_types'; interface ThresholdRuleFieldReadOnlyProps { fieldName: keyof DiffableThresholdFields; @@ -34,6 +33,6 @@ export function ThresholdRuleFieldReadOnly({ case 'type': return null; default: - return assertUnreachable(fieldName); + return null; // Will replace with `assertUnreachable(fieldName)` once all fields are implemented } } From 3753f044ddd65963f72c161c649f33233237f108 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Wed, 18 Sep 2024 09:16:20 +0200 Subject: [PATCH 5/7] Remove `DiffableAllFields` type from field components --- .../fields/data_source/data_source.tsx | 4 ++-- .../fields/description/description.tsx | 12 ++++++------ .../final_readonly/fields/eql_query/eql_query.tsx | 9 ++++++--- .../final_readonly/fields/esql_query/esql_query.tsx | 4 ++-- .../final_readonly/fields/kql_query/index.tsx | 7 ++++--- .../fields/kql_query/inline_kql_query.tsx | 4 ++-- .../fields/kql_query/saved_kql_query.tsx | 8 ++++---- .../machine_learning_job_id.tsx | 4 ++-- .../final_readonly/fields/name/name.tsx | 12 ++++++------ .../final_readonly/fields/tags/tags.tsx | 4 ++-- .../fields/threat_query/threat_query.tsx | 4 ++-- .../final_readonly/storybook/mocks.ts | 13 ++++++++----- 12 files changed, 46 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.tsx index 29518981011fa..2a7bff6ff8b2d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/data_source/data_source.tsx @@ -8,13 +8,13 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import { DataSourceType } from '../../../../../../../../../common/api/detection_engine'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { RuleDataSource } from '../../../../../../../../../common/api/detection_engine'; import { Index, DataViewId, DataViewIndexPattern } from '../../../../rule_definition_section'; import * as ruleDetailsI18n from '../../../../translations'; import { assertUnreachable } from '../../../../../../../../../common/utility_types'; interface DataSourceReadOnlyProps { - dataSource: DiffableAllFields['data_source']; + dataSource?: RuleDataSource; } export function DataSourceReadOnly({ dataSource }: DataSourceReadOnlyProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx index 34ff5b3013b1d..14fa7be6eca3e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx @@ -8,18 +8,18 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { RuleDescription } from '../../../../../../../../../common/api/detection_engine'; -interface RuleDescriptionProps { - description: DiffableAllFields['name']; +interface DescriptionProps { + description: RuleDescription; } -function RuleDescription({ description }: RuleDescriptionProps) { +function Description({ description }: DescriptionProps) { return <>{description}; } interface DescriptionReadOnlyProps { - description: DiffableAllFields['description']; + description: RuleDescription; } export function DescriptionReadOnly({ description }: DescriptionReadOnlyProps) { @@ -28,7 +28,7 @@ export function DescriptionReadOnly({ description }: DescriptionReadOnlyProps) { listItems={[ { title: ruleDetailsI18n.DESCRIPTION_FIELD_LABEL, - description: , + description: , }, ]} /> diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx index 3238e7bb7eeef..b38ecf3af1891 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx @@ -8,14 +8,17 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import type { EuiDescriptionListProps } from '@elastic/eui'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { + RuleDataSource, + RuleEqlQuery, +} from '../../../../../../../../../common/api/detection_engine'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; import { Query, Filters } from '../../../../rule_definition_section'; import { getDataSourceProps, typeCheckFilters } from '../../../../helpers'; interface EqlQueryReadOnlyProps { - eqlQuery: DiffableAllFields['eql_query']; - dataSource: DiffableAllFields['data_source']; + eqlQuery: RuleEqlQuery; + dataSource?: RuleDataSource; } export function EqlQueryReadOnly({ eqlQuery, dataSource }: EqlQueryReadOnlyProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.tsx index ec110bd034b67..9277d2ded7a7d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/esql_query/esql_query.tsx @@ -9,10 +9,10 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; import { Query } from '../../../../rule_definition_section'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { RuleEsqlQuery } from '../../../../../../../../../common/api/detection_engine'; interface EsqlQueryReadonlyProps { - esqlQuery: DiffableAllFields['esql_query']; + esqlQuery: RuleEsqlQuery; } export function EsqlQueryReadOnly({ esqlQuery }: EsqlQueryReadonlyProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/index.tsx index a2dd75e188a0c..d5bea0866c22f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/index.tsx @@ -8,7 +8,8 @@ import React from 'react'; import { KqlQueryType } from '../../../../../../../../../common/api/detection_engine'; import type { - DiffableAllFields, + DiffableRuleTypes, + RuleDataSource, RuleKqlQuery, } from '../../../../../../../../../common/api/detection_engine'; import { InlineKqlQueryReadOnly } from './inline_kql_query'; @@ -17,8 +18,8 @@ import { assertUnreachable } from '../../../../../../../../../common/utility_typ interface KqlQueryReadOnlyProps { kqlQuery: RuleKqlQuery; - dataSource: DiffableAllFields['data_source']; - ruleType: DiffableAllFields['type']; + dataSource?: RuleDataSource; + ruleType: DiffableRuleTypes; } export function KqlQueryReadOnly({ kqlQuery, dataSource, ruleType }: KqlQueryReadOnlyProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx index a70909745d8dc..22140a714566a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx @@ -9,8 +9,8 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import type { EuiDescriptionListProps } from '@elastic/eui'; import type { - DiffableAllFields, InlineKqlQuery, + RuleDataSource, } from '../../../../../../../../../common/api/detection_engine'; import { Query, Filters } from '../../../../rule_definition_section'; import * as ruleDetailsI18n from '../../../../translations'; @@ -25,7 +25,7 @@ const defaultI18nLabels = { interface InlineQueryProps { kqlQuery: InlineKqlQuery; - dataSource?: DiffableAllFields['data_source']; + dataSource?: RuleDataSource; i18nLabels?: { query: string; language: string; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx index d7741f41af820..5f50a9c1b9eae 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/saved_kql_query.tsx @@ -10,8 +10,8 @@ import { EuiDescriptionList } from '@elastic/eui'; import type { EuiDescriptionListProps } from '@elastic/eui'; import type { SavedKqlQuery, - DiffableRule, - DiffableAllFields, + RuleDataSource, + DiffableRuleTypes, } from '../../../../../../../../../common/api/detection_engine'; import { Query, SavedQueryName, Filters } from '../../../../rule_definition_section'; import * as ruleDetailsI18n from '../../../../translations'; @@ -21,8 +21,8 @@ import { getDataSourceProps, getQueryLanguageLabel } from '../../../../helpers'; interface SavedQueryProps { kqlQuery: SavedKqlQuery; - dataSource?: DiffableAllFields['data_source']; - ruleType: DiffableRule['type']; + dataSource?: RuleDataSource; + ruleType: DiffableRuleTypes; } export function SavedKqlQueryReadOnly({ kqlQuery, dataSource, ruleType }: SavedQueryProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.tsx index b177da1467910..570c58539ea84 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/machine_learning_job_id/machine_learning_job_id.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import { MachineLearningJobList } from '../../../../rule_definition_section'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { MachineLearningJobId } from '../../../../../../../../../common/api/detection_engine'; import * as ruleDetailsI18n from '../../../../translations'; interface MachineLearningJobIdProps { - machineLearningJobId: DiffableAllFields['machine_learning_job_id']; + machineLearningJobId: MachineLearningJobId; } export function MachineLearningJobIdReadOnly({ machineLearningJobId }: MachineLearningJobIdProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx index 65743470629ea..e6c5039e579e6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx @@ -8,18 +8,18 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { RuleName } from '../../../../../../../../../common/api/detection_engine'; -interface RuleNameProps { - name: DiffableAllFields['name']; +interface NameProps { + name: RuleName; } -function RuleName({ name }: RuleNameProps) { +function Name({ name }: NameProps) { return <>{name}; } interface NameReadOnlyProps { - name: DiffableAllFields['name']; + name: RuleName; } export function NameReadOnly({ name }: NameReadOnlyProps) { @@ -28,7 +28,7 @@ export function NameReadOnly({ name }: NameReadOnlyProps) { listItems={[ { title: ruleDetailsI18n.NAME_FIELD_LABEL, - description: , + description: , }, ]} /> diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx index 31ef04d6309fc..dbb7928b5f22e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/tags/tags.tsx @@ -8,11 +8,11 @@ import React from 'react'; import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; -import type { DiffableAllFields } from '../../../../../../../../../common/api/detection_engine'; +import type { RuleTagArray } from '../../../../../../../../../common/api/detection_engine'; import { Tags } from '../../../../rule_about_section'; interface TagsReadOnlyProps { - tags: DiffableAllFields['tags']; + tags: RuleTagArray; } export function TagsReadOnly({ tags }: TagsReadOnlyProps) { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.tsx index 6092fd8a0e0ce..b321213b75ad5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/threat_query/threat_query.tsx @@ -7,8 +7,8 @@ import React from 'react'; import type { - DiffableAllFields, InlineKqlQuery, + RuleDataSource, } from '../../../../../../../../../common/api/detection_engine'; import * as ruleDetailsI18n from '../../../../translations'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; @@ -22,7 +22,7 @@ const i18nLabels = { export interface ThreatQueryReadOnlyProps { threatQuery: InlineKqlQuery; - dataSource: DiffableAllFields['data_source']; + dataSource?: RuleDataSource; } export const ThreatQueryReadOnly = ({ threatQuery, dataSource }: ThreatQueryReadOnlyProps) => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts index 2565ddbd04bf3..854251450809f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/storybook/mocks.ts @@ -9,7 +9,8 @@ import type { FieldFormatsStartCommon } from '@kbn/field-formats-plugin/common'; import { DataView } from '@kbn/data-views-plugin/common'; import { DataSourceType, KqlQueryType } from '../../../../../../../../common/api/detection_engine'; import type { - DiffableAllFields, + DataSourceDataView, + DataSourceIndexPatterns, DiffableCommonFields, DiffableCustomQueryFields, DiffableEqlFields, @@ -18,6 +19,8 @@ import type { DiffableRule, DiffableSavedQueryFields, DiffableThreatMatchFields, + InlineKqlQuery, + RuleEqlQuery, SavedKqlQuery, } from '../../../../../../../../common/api/detection_engine'; import { DEFAULT_MAX_SIGNALS } from '../../../../../../../../common/constants'; @@ -59,7 +62,7 @@ export const savedQueryResponse = { namespaces: ['default'], }; -export const inlineKqlQuery: DiffableAllFields['kql_query'] = { +export const inlineKqlQuery: InlineKqlQuery = { type: KqlQueryType.inline_query, query: 'event.action: "user_login" and source.ip: "192.168.1.100"', language: 'kuery', @@ -71,18 +74,18 @@ export const savedKqlQuery: SavedKqlQuery = { saved_query_id: 'fake-saved-query-id', }; -export const eqlQuery: DiffableAllFields['eql_query'] = { +export const eqlQuery: RuleEqlQuery = { query: 'process where process.name == "powershell.exe" and process.args : "* -EncodedCommand *"', language: 'eql', filters, }; -export const dataSourceWithIndexPatterns: DiffableAllFields['data_source'] = { +export const dataSourceWithIndexPatterns: DataSourceIndexPatterns = { type: DataSourceType.index_patterns, index_patterns: ['logs-*'], }; -export const dataSourceWithDataView: DiffableAllFields['data_source'] = { +export const dataSourceWithDataView: DataSourceDataView = { type: DataSourceType.data_view, data_view_id: 'logs-*', }; From 7f44356081f26c1f235ef291592f348eaffacb92 Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Wed, 18 Sep 2024 10:18:26 +0200 Subject: [PATCH 6/7] Rewrite type check for `Filters` component to a type guard --- .../components/rule_details/helpers.ts | 12 +++--------- .../final_readonly/fields/eql_query/eql_query.tsx | 8 +++----- .../fields/kql_query/inline_kql_query.tsx | 8 +++----- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts index 9810cd4882cc7..105d8895ed6b7 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts @@ -77,16 +77,10 @@ export function getQueryLanguageLabel(language: string) { } /** - * Assigns type `Filter` to items that have a `meta` property. Removes any other items. + * Assigns type `Filter[]` to an array if every item in has a `meta` property. */ -export function typeCheckFilters(filters: unknown[]): Filter[] { - return filters.filter((f) => { - if (typeof f === 'object' && f !== null && 'meta' in f) { - return true; - } - - return false; - }) as Filter[]; +export function isFilters(maybeFilters: unknown[]): maybeFilters is Filter[] { + return maybeFilters.every((f) => typeof f === 'object' && f !== null && 'meta' in f); } type DataSourceProps = diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx index b38ecf3af1891..f94f0bbfbe6c8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/eql_query/eql_query.tsx @@ -14,7 +14,7 @@ import type { } from '../../../../../../../../../common/api/detection_engine'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; import { Query, Filters } from '../../../../rule_definition_section'; -import { getDataSourceProps, typeCheckFilters } from '../../../../helpers'; +import { getDataSourceProps, isFilters } from '../../../../helpers'; interface EqlQueryReadOnlyProps { eqlQuery: RuleEqlQuery; @@ -29,14 +29,12 @@ export function EqlQueryReadOnly({ eqlQuery, dataSource }: EqlQueryReadOnlyProps }, ]; - const filters = typeCheckFilters(eqlQuery.filters); - - if (filters.length > 0) { + if (isFilters(eqlQuery.filters) && eqlQuery.filters.length > 0) { const dataSourceProps = getDataSourceProps(dataSource); listItems.push({ title: descriptionStepI18n.FILTERS_LABEL, - description: , + description: , }); } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx index 22140a714566a..54d3836573ab5 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/kql_query/inline_kql_query.tsx @@ -15,7 +15,7 @@ import type { import { Query, Filters } from '../../../../rule_definition_section'; import * as ruleDetailsI18n from '../../../../translations'; import * as descriptionStepI18n from '../../../../../../../rule_creation_ui/components/description_step/translations'; -import { getDataSourceProps, getQueryLanguageLabel, typeCheckFilters } from '../../../../helpers'; +import { getDataSourceProps, getQueryLanguageLabel, isFilters } from '../../../../helpers'; const defaultI18nLabels = { query: descriptionStepI18n.QUERY_LABEL, @@ -49,14 +49,12 @@ export function InlineKqlQueryReadOnly({ }, ]; - const filters = typeCheckFilters(kqlQuery.filters); - - if (filters.length > 0) { + if (isFilters(kqlQuery.filters) && kqlQuery.filters.length > 0) { const dataSourceProps = getDataSourceProps(dataSource); listItems.push({ title: i18nLabels.filters, - description: , + description: , }); } From f89e47613bf528de50571615fbe2a0e6b8c53d7a Mon Sep 17 00:00:00 2001 From: Nikita Indik Date: Wed, 18 Sep 2024 16:52:21 +0200 Subject: [PATCH 7/7] Address code review comments --- .../components/rule_details/helpers.ts | 7 +++++-- .../fields/description/description.tsx | 16 ++++++++-------- .../final_readonly/fields/name/name.tsx | 16 ++++++++-------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts index 105d8895ed6b7..08e4c9535ae91 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/helpers.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { isPlainObject } from 'lodash'; import type { Filter } from '@kbn/es-query'; import type { DiffableAllFields, @@ -77,10 +78,12 @@ export function getQueryLanguageLabel(language: string) { } /** - * Assigns type `Filter[]` to an array if every item in has a `meta` property. + * Assigns type `Filter[]` to an array if every item in it has a `meta` property. */ export function isFilters(maybeFilters: unknown[]): maybeFilters is Filter[] { - return maybeFilters.every((f) => typeof f === 'object' && f !== null && 'meta' in f); + return maybeFilters.every( + (f) => typeof f === 'object' && f !== null && 'meta' in f && isPlainObject(f.meta) + ); } type DataSourceProps = diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx index 14fa7be6eca3e..add624ba15a6d 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/description/description.tsx @@ -10,14 +10,6 @@ import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; import type { RuleDescription } from '../../../../../../../../../common/api/detection_engine'; -interface DescriptionProps { - description: RuleDescription; -} - -function Description({ description }: DescriptionProps) { - return <>{description}; -} - interface DescriptionReadOnlyProps { description: RuleDescription; } @@ -34,3 +26,11 @@ export function DescriptionReadOnly({ description }: DescriptionReadOnlyProps) { /> ); } + +interface DescriptionProps { + description: RuleDescription; +} + +function Description({ description }: DescriptionProps) { + return <>{description}; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx index e6c5039e579e6..a611f9821d54e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/components/rule_details/three_way_diff/final_readonly/fields/name/name.tsx @@ -10,14 +10,6 @@ import { EuiDescriptionList } from '@elastic/eui'; import * as ruleDetailsI18n from '../../../../translations'; import type { RuleName } from '../../../../../../../../../common/api/detection_engine'; -interface NameProps { - name: RuleName; -} - -function Name({ name }: NameProps) { - return <>{name}; -} - interface NameReadOnlyProps { name: RuleName; } @@ -34,3 +26,11 @@ export function NameReadOnly({ name }: NameReadOnlyProps) { /> ); } + +interface NameProps { + name: RuleName; +} + +function Name({ name }: NameProps) { + return <>{name}; +}