Skip to content

Commit

Permalink
[Security Solution][Detections] Associate Endpoint Exceptions List to…
Browse files Browse the repository at this point in the history
… Rule during rule creation/update (#71794)

* Add checkbox to associate rule with global endpoint exception list

This works on creation, now we need edit.

* Fix DomNesting error on ML Card Description

EuiText generates a div, but this is inside of an EuiCard which is a
paragraph. Defines a span with equivalent styles, instead.

* Change default stack of alerts histogram to signal.rule.name
  • Loading branch information
rylnd committed Jul 15, 2020
1 parent 3ecce04 commit ca63513
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ const NO_LEGEND_DATA: LegendItem[] = [];
export const AlertsHistogramPanel = memo<AlertsHistogramPanelProps>(
({
chartHeight,
defaultStackByOption = alertsHistogramOptions[0],
defaultStackByOption = alertsHistogramOptions[8], // signal.rule.name
deleteQuery,
filters,
headerChildren,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
*/

import { FormattedMessage } from '@kbn/i18n/react';
import { EuiText, EuiLink } from '@elastic/eui';
import { EuiLink } from '@elastic/eui';
import styled from 'styled-components';
import React from 'react';

import { ML_TYPE_DESCRIPTION } from './translations';
Expand All @@ -15,11 +16,15 @@ interface MlCardDescriptionProps {
hasValidLicense?: boolean;
}

const SmallText = styled.span`
font-size: ${({ theme }) => theme.eui.euiFontSizeS};
`;

const MlCardDescriptionComponent: React.FC<MlCardDescriptionProps> = ({
subscriptionUrl,
hasValidLicense = false,
}) => (
<EuiText size="s">
<SmallText>
{hasValidLicense ? (
ML_TYPE_DESCRIPTION
) : (
Expand All @@ -38,7 +43,7 @@ const MlCardDescriptionComponent: React.FC<MlCardDescriptionProps> = ({
}}
/>
)}
</EuiText>
</SmallText>
);

MlCardDescriptionComponent.displayName = 'MlCardDescriptionComponent';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const stepAboutDefaultValue: AboutStepRule = {
author: [],
name: '',
description: '',
isAssociatedToEndpointList: false,
isBuildingBlock: false,
isNew: true,
severity: { value: 'low', mapping: [] },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ describe('StepAboutRuleComponent', () => {
await wait();
const expected: Omit<AboutStepRule, 'isNew'> = {
author: [],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
license: '',
ruleNameOverride: '',
Expand Down Expand Up @@ -223,6 +224,7 @@ describe('StepAboutRuleComponent', () => {
await wait();
const expected: Omit<AboutStepRule, 'isNew'> = {
author: [],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
license: '',
ruleNameOverride: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,20 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
}}
/>
<EuiSpacer size="l" />
<EuiFormRow label={I18n.BUILDING_BLOCK} isInvalid={false} fullWidth>
<EuiFormRow label={I18n.GLOBAL_ENDPOINT_EXCEPTION_LIST} fullWidth>
<CommonUseField
path="isAssociatedToEndpointList"
componentProps={{
idAria: 'detectionEngineStepAboutRuleAssociatedToEndpointList',
'data-test-subj': 'detectionEngineStepAboutRuleAssociatedToEndpointList',
euiFieldProps: {
fullWidth: true,
isDisabled: isLoading,
},
}}
/>
</EuiFormRow>
<EuiFormRow label={I18n.BUILDING_BLOCK} fullWidth>
<CommonUseField
path="isBuildingBlock"
componentProps={{
Expand All @@ -291,7 +304,6 @@ const StepAboutRuleComponent: FC<StepAboutRuleProps> = ({
euiFieldProps: {
fullWidth: true,
isDisabled: isLoading,
placeholder: '',
},
}}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ export const schema: FormSchema = {
),
labelAppend: OptionalFieldLabel,
},
isAssociatedToEndpointList: {
type: FIELD_TYPES.CHECKBOX,
label: i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRule.fieldAssociatedToEndpointListLabel',
{
defaultMessage: 'Associate rule to Global Endpoint Exception List',
}
),
labelAppend: OptionalFieldLabel,
},
severity: {
value: {
type: FIELD_TYPES.SUPER_SELECT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ export const ADD_FALSE_POSITIVE = i18n.translate(
defaultMessage: 'Add false positive example',
}
);

export const GLOBAL_ENDPOINT_EXCEPTION_LIST = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.endpointExceptionListLabel',
{
defaultMessage: 'Global endpoint exception list',
}
);

export const BUILDING_BLOCK = i18n.translate(
'xpack.securitySolution.detectionEngine.createRule.stepAboutRuleForm.buildingBlockLabel',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export const mockRuleWithEverything = (id: string): Rule => ({
export const mockAboutStepRule = (isNew = false): AboutStepRule => ({
isNew,
author: ['Elastic'],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
timestampOverride: '',
ruleNameOverride: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export const formatAboutStepData = (aboutStepData: AboutStepRule): AboutStepRule
riskScore,
severity,
threat,
isAssociatedToEndpointList,
isBuildingBlock,
isNew,
note,
Expand All @@ -163,6 +164,13 @@ export const formatAboutStepData = (aboutStepData: AboutStepRule): AboutStepRule
const resp = {
author: author.filter((item) => !isEmpty(item)),
...(isBuildingBlock ? { building_block_type: 'default' } : {}),
...(isAssociatedToEndpointList
? {
exceptions_list: [
{ id: 'endpoint_list', namespace_type: 'agnostic', type: 'endpoint' },
] as AboutStepRuleJson['exceptions_list'],
}
: {}),
false_positives: falsePositives.filter((item) => !isEmpty(item)),
references: references.filter((item) => !isEmpty(item)),
risk_score: riskScore.value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ describe('rule helpers', () => {
title: 'Titled timeline',
},
};
const aboutRuleStepData = {

const aboutRuleStepData: AboutStepRule = {
author: [],
description: '24/7',
falsePositives: ['test'],
isAssociatedToEndpointList: false,
isBuildingBlock: false,
isNew: false,
license: 'Elastic License',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu
const {
author,
building_block_type: buildingBlockType,
exceptions_list: exceptionsList,
license,
risk_score_mapping: riskScoreMapping,
rule_name_override: ruleNameOverride,
Expand All @@ -138,6 +139,7 @@ export const getAboutStepsData = (rule: Rule, detailsView: boolean): AboutStepRu
return {
isNew: false,
author,
isAssociatedToEndpointList: exceptionsList?.some(({ id }) => id === 'endpoint_list') ?? false,
isBuildingBlock: buildingBlockType !== undefined,
license: license ?? '',
ruleNameOverride: ruleNameOverride ?? '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
SeverityMapping,
TimestampOverride,
} from '../../../../../common/detection_engine/schemas/common/schemas';
import { List } from '../../../../../common/detection_engine/schemas/types';

export interface EuiBasicTableSortTypes {
field: string;
Expand Down Expand Up @@ -65,6 +66,7 @@ export interface AboutStepRule extends StepRuleData {
author: string[];
name: string;
description: string;
isAssociatedToEndpointList: boolean;
isBuildingBlock: boolean;
severity: AboutStepSeverity;
riskScore: AboutStepRiskScore;
Expand Down Expand Up @@ -136,6 +138,7 @@ export interface DefineStepRuleJson {
export interface AboutStepRuleJson {
author: Author;
building_block_type?: BuildingBlockType;
exceptions_list?: List[];
name: string;
description: string;
license: License;
Expand Down

0 comments on commit ca63513

Please sign in to comment.